MongoDB

初步探索 MongoDB

教學

docker-compose.yml

version: '3.8'

services:

    db:
        image: mongo
        restart: always
        container_name: mongodb
        ports:
            - "27017:27017"
        environment:
            MONGO_INITDB_ROOT_USERNAME: root
            MONGO_INITDB_ROOT_PASSWORD: password
        volumes:
            - mongo_data:/data/db

volumes:
  mongo_data:

進入容器

docker exec -it mongodb bash

連接

mongosh admin -u root -p password

顯示 databases

show dbs

顯示 collections (類似 RMDBS 中的 table)

show collections

顯示 databases version

db.version()

建立新的不存在 database

use test

MongoDB Shell CRUD

官方文件可參考 mongodb-shell

  • Insert a Single Document
use test

db.movies.insertOne(
  {
    title: "The Favourite",
    genres: [ "Drama", "History" ],
    runtime: 121,
    rated: "R",
    year: 2018,
    directors: [ "Yorgos Lanthimos" ],
    cast: [ "Olivia Colman", "Emma Stone", "Rachel Weisz" ],
    type: "movie"
  }
)

insertOne()

returns a document that includes the newly inserted document's _id field value.

取回資料

db.movies.find( { title: "The Favourite" } )
  • Insert Multiple Documents
use test

db.movies.insertMany([
   {
      title: "Jurassic World: Fallen Kingdom",
      genres: [ "Action", "Sci-Fi" ],
      runtime: 130,
      rated: "PG-13",
      year: 2018,
      directors: [ "J. A. Bayona" ],
      cast: [ "Chris Pratt", "Bryce Dallas Howard", "Rafe Spall" ],
      type: "movie"
    },
    {
      title: "Tag",
      genres: [ "Comedy", "Action" ],
      runtime: 105,
      rated: "R",
      year: 2018,
      directors: [ "Jeff Tomsic" ],
      cast: [ "Annabelle Wallis", "Jeremy Renner", "Jon Hamm" ],
      type: "movie"
    }
])

insertMany()

returns a document that includes the newly inserted documents' _id field values.

取回全部的資料

db.movies.find( {} )

說明語法

use test
db.movies.find()

類似 RMDBS 中的

SELECT * FROM movies

Specify Equality Condition

use test
db.movies.find( { title: "The Favourite" } )

類似 RMDBS 中的

SELECT * FROM movies WHERE title = "The Favourite"

Specify Conditions Using Query Operators

use test
db.movies.find( { genres: { $in: [ "Drama", "PG-13" ] } } )

類似 RMDBS 中的

SELECT * FROM movies WHERE genres in ("Drama", "PG-13")

Specify Logical Operators(AND)

use test
db.movies.find( { rated: "R", runtime: { $gte: 120 } } )

rated 必須是 R, 然後 runtime 必須大於等於 120

Specify Logical Operators(OR)

use test
db.movies.find( {
     year: 2018,
     $or: [ { runtime: { $gte: 100 } }, { title: "Tag" } ]
} )

year 必須是 2018, 然後 runtime 必須大於等於 100 或 title 等於 Tag.

  • Update a Single Document
use test

db.movies.updateOne(
  { title: "Jurassic World: Fallen Kingdom" }, {
    $set: {runtime: 77}
  })

db.movies.find( { title: "Jurassic World: Fallen Kingdom" } )

db.movies.updateOne(
  { title: "Jurassic World: Fallen Kingdom" },{
    $set: {runtime: "77"},
    $currentDate: { lastUpdated: true }
})

如果沒有的欄位, 會自動建立.

有關 $currentDate 的說明可參考 currentDate

  • Update Multiple Documents
use test
db.movies.updateMany(
  { runtime: { $lt: 100 } },
  {
    $set: { runtime: 5, nights: 1 }
  }
)

db.movies.find( { nights: 1 } )
  • Replace a Document
db.movies.replaceOne(
  { _id: ObjectId("64741819dcd1cd7e37d54731") },
  { test123: 893421, limit: 5000, products: [ "Investment", "Brokerage" ] }
)

db.movies.findOne( { _id: ObjectId("64741819dcd1cd7e37d54731") } )
  • Delete All Documents
use test
db.movies.deleteMany({})
  • Delete All Documents that Match a Condition
use test
db.movies.deleteMany( { title: "Tag" } )
  • Delete Only One Document that Matches a Condition
use test
db.movies.deleteOne( { _id: ObjectId("64741819dcd1cd7e37d54731") } )

db.movies.findOne( { _id: ObjectId("64741819dcd1cd7e37d54731") } )

MongoDB GUI TOOL

請直接到這邊下載 MongoDB Compass (GUI)

設定 Authentication Method

alt tag

如果順利登入的話, 會看到類似的介面

alt tag

PyMongo

透過 PyMongo documentation 把玩 MongoDB

安裝 pymongo

pip3 install pymongo

範例 code

from pymongo import MongoClient

client = MongoClient('mongodb://root:password@localhost:27017/')

db = client['test']

movies = db['movies']

def insert_demo():
    # insert
    new_profile = {'user_id': 213, 'name': 'Alan'}
    movies.insert_one(new_profile)

    # read
    for move in movies.find():
        print(move)

def update_demo():
    movies.update_one({'user_id': 213}, {'$set': {'user_id': 30}})

    # read
    for move in movies.find():
        print(move)

insert_demo()
# update_demo()

Reference