Mongodb
安装
单机配置
storage:
dbPath: /var/lib/mongo
net:
port: 27017
bindIp: 0.0.0.0
replication:
replSetName: rs # 定义副本集的名称
启动服务:
systemctl enable --now mongod
默认服务端口为:TCP/27017
和UNIX/tmp/mongodb-27017.sock
。默认监听地址为127.0..0.1
,可改为0.0.0.0
以监听所有地址。
MongoDB Shell
mongosh
:a 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
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"
},
//...
}
}
}
}
文档结构
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