Mongodb

安装

单机配置

storage:
  dbPath: /var/lib/mongo
net:
  port: 27017
  bindIp: 0.0.0.0
replication:
   replSetName: rs # 定义副本集的名称

启动服务:

systemctl enable --now mongod

默认服务端口为:TCP/27017UNIX/tmp/mongodb-27017.sock。默认监听地址为127.0..0.1,可改为0.0.0.0以监听所有地址。

MongoDB Shell

mongosha fully functional JavaScript and Node.js 14.x REPL environment.

关键字为小写(大小写敏感)。

SQL to MongoDB Mapping Chart — MongoDB Manual

用户管理
use admin
db.createUser({   // => 创建用户
  user: 'root',
  pwd: '123456',
  roles:[{ role: 'root', db: 'admin' }]
})
db.getUser("root")

db是关键字,表示当前数据库;

常用命令
db.auth("root","123456")  // 如果启用授权验证,则在进入shell后需要提供用户凭据
db.stats()
db.adminCommand({getParameter:"*"})
db._adminCommand({getCmdLineOpts: 1})

集群配置

在集群每个节点安装Mongodb服务。

replica set

replica set包含一组维护相同数据集的mongod实例,提供冗余和高可靠性,提高读取速率。

一个集群仅包含一个主节点。数据需要从主节点写入,次级节点根据主节点的操作记录修改本地数据以与主节点保持一致。节点之间通过发送心跳信息检测可用性。当主节点失效,次级节点将发起竞选以产生新的主节点。

副本集配置

启动Mongo Shell,执行以下命令==将当前节点设置为主节点==。如果返回结果显示ok=1,则集群配置成功。

rs.initiate({
    "_id": "rs",
    "members": [
        { "_id": 1, "host": "172.17.218.11:27017" },
        { "_id": 2, "host": "172.17.218.12:27017" },
        { "_id": 3, "host": "172.17.218.13:27017" }
    ]
})

当节点配置使用replica set后,启动shell时会自动创建replica set管理对象rs,用于执行replica set得初始化和管理。

MongoDB Replica Set副本集配置 - 掘金 (juejin.cn)

验证集群
rs.status()  // 查看当前复制集的状态
// {  "set": "rs",  "members": [...], "ok": 1 }
rs.isMaster() // 返回当前节点是否为集群主节点得相关信息
在线集群配置
conf = rs.conf() 
// 修改conf的属性
rs.reconfig(conf)

Sharded Cluster

Sharding — MongoDB Manual

docker配置

replica set

MongoDB Replica Set / docker-compose / mongoose transaction with persistent volume (github.com)

存储引擎

Storage Engines — MongoDB Manual

写入数据

数据模型

同一个集合中的文档不需要具有相同的字段和数据类型;可以灵活更新文档的字段以及数据类型;

可以在创建文档集合时声明JSON Schema以限制数据操作。

db.createCollection("students", {
   validator: {
      $jsonSchema: {
         bsonType: "object",
         required: [ "name", "year", "major", "address" ],
         properties: {
            name: {
               bsonType: "string",
               description: "must be a string and is required"
            },
            year: {
               bsonType: "int",
               minimum: 2017,
               maximum: 3017,
               description: "must be an integer in [ 2017, 3017 ] and is required"
            },
            major: {
               enum: [ "Math", "English", "Computer Science", "History", null ],
               description: "can only be one of the enum values and is required"
            },
            //...
         }
      }
   }
}

字段类型说明

文档结构

image-20211230085728177

Data Modeling Introduction — MongoDB Manual

写入操作

插入单个文档
db.collection.insertOne(
   { item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } }
)
插入多个文档
db.collection.insertMany([
   { item: "journal", qty: 25, tags: ["blank", "red"], size: { h:14, w:21, uom:"cm" } },
   { item: "mat", qty: 85, tags: ["gray"], size: { h:27.9, w:35.5, uom:"cm" } },
   { item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h:19, w:22.85, uom:"cm" } }
])

如果文档不包含_id字段(主键),则自动为文档添加_id字段:{"_id": ObjectId("value")}。如果指定了_id,则需要保证_id唯一,否则会产生异常。

如果文档集合collection不存在,则自动创建集合;

Insert Methods — MongoDB Manual

更新文档
db.inventory.updateOne(  // updateMany(), replaceOne()
   { item: "paper" },
   {
     $set: { "size.uom": "cm", status: "P" },
     $currentDate: { lastModified: true }
   }
)
删除文档
db.collection.deleteMany(conditions)
db.collection.deleteOne( conditions )

conditions为空字典,则删除集合的所有文档。

批量写操作

一次执行多个写操作。

Bulk Write Operations — MongoDB Manual

查询

show dbs
use <db_name>
show collections
show users  // users of current database
等式查询
db.inventory.find( {item:"canvas"} ) # => SELECT * FROM db.inventory WHERE item='canvas'

find()的参数为查询条件构成的文档;如果字段为空,则返回所有文档。

字段值可以是嵌套的子文档值;或者指定子文档字段:field.nestfield

数组字段查询:指定数组所有元素;$all运算符不限定数组元素顺序,指定单个元素查询数组字段是否包含该元素。

指定查询条件
{ <field1>: { <operator1>: <value1> }, ... }

比较运算符:$in,$nin,$lt,$gt,$gte,$lte,$eq,$ne

逻辑运算符:默认情况下,查询条件文档字段之间为AND连接;使用$or构造OR连接

db.inventory.find( {
     status: "A",
     $or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
})

逻辑运算符可以嵌套使用,构造复杂查询条件。

正则表达式运算符$regex(MongDB使用PCRE)

{ <field>: { $regex: 'pattern', $options: '<options>' } }
{ <field>: /pattern/<options> }
限定返回字段
db.collection.find(condition, projection)

projection指定返回的字段(为指定该参数返回所有字段),要返回字段名对应的值为1;默认返回_id字段。如果仅包含值为0的字段声明,则返回除声明字段外的字段。

{ "field1": 1, "field2": 1, ..., "_id": 0}

Python API

Python API语法pymongo基本和Mongo Shell一致。

连接
from pymongo import MongoClient
client = MongoClient("mongodb://root:passwd@server_name/db", authSource="admin")
数据库信息
db = client.get_database(name=None) # => client['db_name'] => client.db_name
db.list_collections()               # -> Iterator[collection]
db.list_collection_names()          # -> List[str]
c = db.get_collection('collection') # => db['collection'] => db.collection
写入
db.collection.insert(dict_item)
db.collection.insert_many([dict_item,...])
查询
db.collection.find({...})       # -> Iterator(dict)
db.collection.find_one({...})   # -> dict