https://docs.mongodb.com/v4.2/reference/method/db.createCollection/
db.createCollection( <name>,
{
capped: <boolean>,
autoIndexId: <boolean>,
size: <number>,
max: <number>,
storageEngine: <document>,
validator: <document>,
validationLevel: <string>,
validationAction: <string>,
indexOptionDefaults: <document>,
viewOn: <string>, // Added in MongoDB 3.4
pipeline: <pipeline>, // Added in MongoDB 3.4
collation: <document>, // Added in MongoDB 3.4
writeConcern: <document>
}
)
name
options
类型:document
描述:集合的相关配置
capped
autoIndexId
3.2版本之后弃用
从4.0版本开始,不能在 local 以外的数据库中设置此选项
官方不推荐使用!!!
_id
字段创建为索引size
max
storageEngine
类型:document
描述:
设定集合使用的存储引擎配置(仅对于 WiredTiger 存储引擎)
格式
{ <storage-engine-name>: <options> }
validator
validationLevel
类型:字符串
描述:确定MongoDB在更新过程中对现有文档应用验证规则的严格程度
"off"
关闭校验规则
"strict" 【默认】
对文档所有的更新和新增操作进行验证
"moderate"
[‘m?d?re?t] 适度的
仅对 已符合校验规则的 现有文档 进行新增和更改验证,对 不符合校验规则的 现有文档不再进行操作校验
validationAction
类型:字符串
描述:对于数据校验无效的文档的处理措施,仅适用于 validationLevel 确定的那些文档
"error"【默认】
如果新增或更新操作不符合校验规则,则mongodb自动报错
在发生写操作之前,文档必须通过校验,否则写操作失败
"warn"
如果新增或更新操作不符合校验规则,mongodb不会报错,但会把错误信息记录在日志中
indexOptionDefaults
viewOn
pipeline
collation
writeConcern
权限控制
具有 readWrite 内建角色的用户具有上述操作的所有权限,可将角色授予现有用户用来执行上述操作
创建固定集合
db.createCollection("log", { capped : true, size : 5242880, max : 5000 } )
创建具有数据校验的集合
db.createCollection( "contacts", {
validator: { $jsonSchema: {
bsonType: "object",
required: [ "phone" ],
properties: {
phone: {
bsonType: "string",
description: "must be a string and is required"
},
email: {
bsonType : "string",
pattern : "@mongodb\.com$",
description: "must be a string and match the regular expression pattern"
},
status: {
enum: [ "Unknown", "Incomplete" ],
description: "can only be one of the enum values"
}
}
} }
} )
插入
db.contacts.insert( { name: "Amanda", status: "Updated" } )
报错
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 121,
"errmsg" : "Document failed validation"
}
})
格式
db.collection.drop( { writeConcern: <document> } )
Returns
true
删除成功
false
集合不存在
查询当前数据库中有哪些集合
格式
db.collection.renameCollection(target, dropTarget)
target
dropTarget
类型:布尔
描述:
true
如果新名称已经存在,则在重命名之前,删除已经存在的新名称集合
false【默认】
如果新名称已经存在,则重命名失败
"errmsg" : "target namespace exists"
示例
db.rrecord.renameCollection("record")
capped collection
具有 固定大小的 存储空间的 集合
特点
基于文档的插入顺序存储于磁盘中
基于插入顺序的 插入和查询操作 具有很高性能
写入速度非常块
查询具有顺序的文档时,查询速度很快
工作机制类似循环缓存区,一旦集合填满了所分配的空间,就会自动删除最旧的文档,用来插入新文档
固定集合可以确保文档的插入顺序,因此不需要为插入顺序建立索引,可以支持非常高的插入吞吐量
在不指定顺序的查询操作中,mongodb 保证查询结果的顺序与插入顺序一致
默认情况下,固定集合有一个_id
字段和建立在其之上的索引
存储空间的大小为 256 的整数倍,最小空间为 4096 字节
限制
与TTL索引不兼容
TTL 是固定集合的替代方案
不能更改文档大小
不能使用 delete 指令删除固定集合中的文档,只能使用 drop 指令删除集合再重新创建
固定集合不能分片
聚合管道阶段中的 $out 结果不能写入固定集合
从MongoDB 4.2开始,事务中的固定集合不支持写数据,但支持读取数据
格式
db.createCollection( <name>, { capped:true, size: <number1>, max: <number2> } )
格式
db.runCommand( "convertToCapped": <name>, size: <number1> )
db.collection.isCapped()
返回结果
应用
存储由大容量系统生成的日志信息,在没有索引的情况下,使用固定集合插入文档的速度接近于将日志信息直接写入文件系统的速度
例如mongodb中的用来同步复制的 oplog 就是一个固定集合
缓存少量的数据
create read update delete
格式
db.collection.insert(
<document or array of documents>,
{
writeConcern: <document>,
ordered: <boolean>
}
)
document or array of documents
{ }
中,如 { doc }
{ }
中,然后一起放在[ ]
中,如[ { doc1 }, { doc2 } ]
writeConcern
【可选】是否使用写入策略
ordered
insert 包含 insertOne 和 insertMany
示例
> db.person.insert([
... {
... name:"lfp",
... age:18,
... birth: new Date("1992-10-24")
... },
... {
... name:"xm",
... age:19,
... birth: new Date("1991-01-22")
... }
... ])
格式
db.collection.insertOne(
<document>,
{
writeConcern: <document>
}
)
格式
db.collection.insertMany(
[ <document 1> , <document 2>, ... ],
{
writeConcern: <document>,
ordered: <boolean>
}
)
_id
字段进行覆盖式更新)格式
db.collection.save(
<document>,
{
writeConcern: <document>
}
)
新版本中有可能被废弃,建议使用 insertOne 或 replaceOne
4.2 版本测试仍可以使用
示例
当插入_id
主键相同的文档时会覆盖
> db.person.save({
... _id:ObjectId("5f2d16c2cbb6771db2cf3db9"),
... name:"lfp",
... age:23,
... birth:new Date("1992-10-24")
... })
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
查询数组元素中是否包含指定的元素,针对的是数组中的每一个元素
{ <array field>: { <operator1>: <value1>, ... } }
例如
db.inventory.find( { dim_cm: { $gt: 25 } } )
db.collection.find(
<query>,
<projection>
)
query【可选】
类型:document
描述
{ }
,将返回集合中所有的文档projection【可选】
类型:document => { field1: <value>, field2: <value> ... }
字段值为1,表示显示此字段(include)
字段值为0,表示不显示此字段(exclude)
_id
字段默认显示,若不想显示则指定 {"_id":0}
不能同时包含 include 和 exclude 行为,除了_id
字段
通过 Projection 操作符指定
在视图中查询时,不能使用 $、$eleMatch、$slice、$meta 操作符
描述
返回指向文档的游标
游标 cursor 指向符合查询条件的文档,find 方法实际返回的是指向文档的游标
文档
返回集合中的所有文档
db.bios.find()
返回符合指定条件的文档
$eq
db.bios.find( { _id : 5 } )
db.bios.find( { "name.last" : "Hopper" } )
db.bios.find(
{ birth : { $gt : new Date(‘1992-01-01‘) } }
)
// 正则
db.bios.find(
{ "name.last" : { $regex : /^N/ } }
)
// 范围,一个子文档中用多个查询操作符表示范围
db.bios.find(
{ birth : { $gt: new Date(‘1940-01-01‘), $lt: new Date(‘1960-01-01‘) } }
)
// 多条件查询
db.bios.find(
{
birth : { $gt : new Date(‘1940-01-01‘) },
death : { $exist : false }
}
)
查询集合或视图中的文档,并返回符合条件的第一个文档
按照自然顺序,即磁盘上文档的顺序,在 capped 集合中,相当于插入顺序
如果没有符合条件的文档,则返回 null
格式
db.collection.find(
<query>,
<projection>
)
Returns
返回文档而非游标
示例
db.bios.findOne(
{
$or: [
{ ‘name.first‘ : /^G/ },
{ birth: { $lt: new Date(‘01/01/1945‘) } }
]
}
)
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string> // Available starting in MongoDB 4.2
}
)
query
类型:document
描述:
更新条件,符合更新条件的文档将被更新
使用与find()方法中相同的查询选择器
update
类型:document 或 pipeline
document
pipeline
4.2版本新增
聚合管道
描述:更新操作
options
upsert
类型:布尔【可选】
true
若没有匹配的文档,会插入当前文档
false 【默认】
若没有匹配的文档,则不插入当前文档
描述:
multi
类型:布尔【可选】
true
更新所有匹配的文档
false【默认】
只更新匹配到的第一个文档
writeConcern
{ w:1 }
【默认】collation
arrayFilters
类型:数组【可选,3.6新增】
一个标识符只能对应一个数组过滤器文档
// INVALID
[
{ "x.a": { $gt: 85 } },
{ "x.b": { $gt: 80 } }
]
// Example 1
[
{ $or: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
// Example 2
[
{ $and: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
// Example 3
[
{ "x.a": { $gt: 85 }, "x.b": { $gt: 80 } }
]
当 更新文档 是对嵌套数组中的元素进行更改,则会出现两个标识符,此时会有两个数组过滤器文档
描述
数组元素的过滤条件,用来确定哪些元素被更新(数组过滤器)
当 update 类型是 document 时,使用 $[ < identifier > ]
来定义一个 标识符,代表元素下标,在 arrayFilters 中用 identifier 代表元素,设定元素的过滤条件
$[ < identifier > ]
整体代表元素下标
都需要用引号包裹 ‘$‘ ‘identifier‘
当 update 类型是 聚合管道时,不能使用 arrayFilters 选项
返回一个 WriteResult 文档,包含操作的状态
Successful Results
执行成功
nMatched
符合条件的文档数量
nUpserted
更新操作插入的文档数量
nModified
更新文档的数量
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Write Concern Errors
执行时发生写入策略错误,需要用 try-catch 捕获
writeConcernError
写入策略错误对象
WriteResult({
"nMatched" : 1,
"nUpserted" : 0,
"nModified" : 1,
"writeConcernError" : {
"code" : 64,
"errmsg" : "waiting for replication timed out at shard-a"
}
})
Errors Unrelated to Write Concern
执行时发生其他错误(非写入策略错误),需要用 try-catch 捕获
write Error
错误对象
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 7,
"errmsg" : "could not contact primary for replica set shard-a"
}
})
数组过滤器
db.students.insertMany([
{ "_id" : 1, "grades" : [ 95, 92, 90 ] },
{ "_id" : 2, "grades" : [ 98, 100, 102 ] },
{ "_id" : 3, "grades" : [ 95, 110, 100 ] }
])
更新
db.students.update(
{ grades: { $gte: 100 } },
{ $set: { "grades.$[element]" : 100 } },
{
multi: true,
arrayFilters: [ { "element": { $gte: 100 } } ]
}
)
格式
db.collection.updateOne(
<filter>,
<update>,
{
upsert: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string> // Available starting in MongoDB 4.2.1
}
)
filter
类型:document
描述:
选择条件,符合条件的文档将被更新
使用与find()方法中相同的查询选择器
如果指定一个空文档{ }
,将更新集合中的第一个文档
writeConcern
Returns
同 update 方法
示例
filter 为空文档
文档
db.members.insertMany([
{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan" },
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 },
{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : 0 }
])
更新
db.members.updateOne(
{ },
{ $set:{ "villations":4 }}
)
格式
db.collection.updateMany(
<filter>,
<update>,
{
upsert: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string> // Available starting in MongoDB 4.2.1
}
)
filter
类型:document
描述:
选择条件,符合条件的文档将被更新
使用与find()方法中相同的查询选择器
如果指定一个空文档{ }
,将更新集合中的所有文档
writeConcern
Returns
方法将返回一个文档,包含以下字段
acknowledged
类型:布尔
true
执行写入策略
false
写入策略被禁用
matchedCount
modifiedCount
upsertedId
_id
示例
filter 为空,更新所有文档
文档
db.members.insertMany([
{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan" },
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 },
{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : 0 }
])
更新
db.members.updateMany(
{ },
{ $set:{ "age":27 }}
)
格式
db.collection.replaceOne(
<filter>,
<replacement>,
{
upsert: <boolean>,
writeConcern: <document>,
collation: <document>,
hint: <document|string> // Available starting in 4.2.1
}
)
filter
类型:document
描述:
选择条件,符合条件的文档将被替换
使用与find()方法中相同的查询选择器
如果指定一个空文档{ }
,将替换集合中的第一个文档
replacement
writeConcern
Returns
同 updateMany
示例
使用 upsert
文档
db.members.insertMany([
{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan", "violations" : 3 },
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 },
{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : 0 }
])
更新
try {
db.members.replaceOne(
{ "name" : "Pizza Rat‘s Pizzaria" },
{ "_id": 4, "name" : "Pizza Rat‘s Pizzaria", "Borough" : "Manhattan", "violations" : 8 },
{ upsert: true }
);
} catch (e){
print(e);
}
upsert : true
选项,没有符合条件的文档时,则插入替换文档db.collection.remove(
<query>,
<justOne>
)
query
{ }
,将删除集合中的所有文档justOne【可选】
类型:布尔
true
仅删除符合条件的第一个文档
false【默认】
删除符合条件的所有文档
描述:是否仅删除第一个符合条件的文档
db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>,
collation: <document>
}
)
query
同上
justOne
同上
writeConcern
返回一个 WriteResult 包含操作状态
Successful Results
执行成功
nRemoved
删除文档的数量
WriteResult({ "nRemoved" : 4 })
Write Concern Errors
执行时发生写入策略错误,需要用 try-catch 捕获
writeConcernError
写入策略错误对象
Errors Unrelated to Write Concern
执行时发生其他错误(非写入策略错误),需要用 try-catch 捕获
write Error
错误对象
格式1,使用 justOne 选项
文档
db.myColl.insert([
{ _id: 1, category: "café", status: "A" },
{ _id: 2, category: "cafe", status: "a" },
{ _id: 3, category: "cafE", status: "a" },
])
删除
db.myColl.remove(
{status:"a"},
true
)
_id
为2 的文档格式2,使用 justOne 选项
删除
db.myColl.remove(
{status:"a"},
{justOne:true}
)
_id
为2 的文档删除集合中所有文档
删除
db.myColl.remove(
{}
)
格式
db.collection.deleteOne(
<filter>,
{
writeConcern: <document>,
collation: <document>
}
)
{ }
,将删除集合中的第一个文档Returns
返回一个文档,包含
acknowledged
类型:布尔
true
执行写入策略
false
写入策略被禁用
deletedCount
格式
db.collection.deleteMany(
<filter>,
{
writeConcern: <document>,
collation: <document>
}
)
{ }
,将删除集合中的所有文档Returns
同 deleteOne
db.collection.find().pretty()
不包含字段 符合条件的操作符
$ne、$nin、$nor、$not
对大多数数据类型,仅当字段值类型和指定值类型相同时进行比较
不同时指定比较规则?
操作符表达式文档 本身 作为 字段/操作符 的值
格式
{ field: { $eq: value } }
// 等价于下面的写法
{ field: <value> }
field : value
形式就是相等条件示例
db.inventory.find( { tags: { $eq: [ "A", "B" ] } } )
db.inventory.find( { tags: [ "A", "B" ] } )
db.inventory.find( { "item.name": { $eq: "ab" } } )
db.inventory.find( { "item.name": "ab" } )
>
指定的值(greater than)格式
{field: {$gt: value} }
示例
db.inventory.update( { "carrier.fee": { $gt: 2 } }, { $set: { price: 9.99 } } )
>=
指定的值(greater then or equal)格式
{field: {$gte: value} }
表示字段的值 等于 指定数组中任意一个元素
如果字段的值是数组类型,则表示字段数组 至少 包含 指定数组中任意一个元素
对同一个字段执行相等性检查时,优于 $or 逻辑操作符
可以通过正则对象表达式 /pattern/
指定匹配的值
在 $in 表达式中不能使用 $regex 操作符表达式
格式
{ field: { $in: [<value1>, <value2>, ... <valueN> ] } }
示例
字段值是数组
文档
{ _id: 1, item: "abc", qty: 10, tags: [ "school", "clothing" ], sale: false }
更新
db.inventory.update(
{ tags: { $in: ["appliances", "school"] } },
{ $set: { sale:true } }
)
正则表达式
db.inventory.find( { tags: { $in: [ /^be/, /^st/ ] } } )
<
指定的值(less than)格式
{field: {$lt: value} }
<=
指定的值(less than or equal)格式
{ field: { $lte: value} }
指定不相等条件,表示字段的值不等于指定的值,或者文档中 不包含该字段(not equal)
该操作符选择性不好,因为它经常匹配索引的很大一部分。因此,很多情况下,带有索引的 $ne 查询的性能并不比不带索引的 $ne 查询性能好
不带索引则必须扫描集合中所有的文档
格式
{field: {$ne: value} }
表示字段的值不等于指定数组中任何一个元素, 或者文档中 不包含该字段(not in)
如果字段的值是数组类型,则表示字段数组中不包含指定数组中任何一个元素
该操作符选择性不好,因为它经常匹配索引的很大一部分。因此,很多情况下,带有索引的 $nin 的查询性能并不比不带索引的 $nin 的查询性能好
不带索引则必须扫描集合中所有的文档
格式
{ field: { $nin: [ value1, value2 ... valueN ]}
示例
db.inventory.update( { tags: { $nin: [ "appliances", "school" ] } }, { $set: { sale: false } } )
格式
{ $and: [ { <expression1> }, { <expression2> } , ... , { <expressionN> } ] }
示例
隐式and
db.inventory.find( { $and: [ { price: { $ne: 1.99 } }, { price: { $exists: true } } ] } )
相等于
将price字段的表达式重组,通过逗号分隔,组成一个表达式列表,用一个子文档表示
db.inventory.find( { price: { $ne: 1.99, $exists: true } } )
使用相同操作符的多个表达式
db.inventory.find( {
$and: [
{ $or: [ { qty: { $lt : 10 } }, { qty : { $gt: 50 } } ] },
{ $or: [ { sale: true }, { price : { $lt : 5 } } ] }
]
} )
格式
{ field: { $not: { <operator-expression> } } }
操作符表达式文档
正则对象表达式
4.0.6版本之后才支持 正则操作符表达式
示例
影响其他字段
db.inventory.find( { price: { $not: { $gt: 1.99 } } } )
正则表达式
db.inventory.find( { item: { $not: /^p.*/ } } )
正则操作符表达式
db.inventory.find( { item: { $not: { $regex: "^p.*" } } } )
db.inventory.find( { item: { $not: { $regex: /^p.*/ } } } )
db.inventory.find( { item: { $not: /^p.*/ } } )
格式
{ $nor: [ { <expression1> }, { <expression2> }, ... { <expressionN> } ] }
值为数组类型,元素为操作符表达式文档
操作符表达式 本身不作为字段的值
一般返回结果可以包括 2^表达式个数 个组合
每个表达式有两种情况,不符合表达式或不包含该字段
示例
一般情况
db.inventory.find( { $nor: [ { price: 1.99 }, { sale: true } ] } )
- 查询条件是:
1. price存在且不等于1.99 且 sale不为true
2. price不存在 且 sale 存在且不为true
3. price存在且不等于1.99 且 sale 不存在
4. price不存在 且 sale 不存在
- 结合 $exists 操作符使用
```sql
db.inventory.find( { $nor: [ { price: 1.99 }, { price: { $exists: false } },
{ sale: true }, { sale: { $exists: false } } ] } )
格式
{ $or: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }
示例
db.inventory.find( { $or: [ { quantity: { $lt: 20 } }, { price: 10 } ] } )
为了支持 $or 查询,需要给 quantity 和 price 字段建立索引
db.inventory.createIndex( { quantity: 1 } )
db.inventory.createIndex( { price: 1 } )
格式
{ field: { $exists: <boolean> } }
值为布尔类型
4.2 版本之前,$type:0 跟 $exists:false 是同义词
表示字段的值是某个类型(BSON type ),或字段值是数组且包含一个该类型的元素
BSON type 可以是对应的数字或别名
当指定字段类型是数组时
[ ]
)当字段类型
类型
Type | Number | Alias | Notes |
---|---|---|---|
Double | 1 | “double” | |
String | 2 | “string” | |
Object | 3 | “object” | |
Array | 4 | “array” | |
Binary data | 5 | “binData” | |
Undefined | 6 | “undefined” | Deprecated. |
ObjectId | 7 | “objectId” | |
Boolean | 8 | “bool” | |
Date | 9 | “date” | |
Null | 10 | “null” | |
Regular Expression | 11 | “regex” | |
DBPointer | 12 | “dbPointer” | Deprecated. |
JavaScript | 13 | “javascript” | |
Symbol | 14 | “symbol” | Deprecated. |
JavaScript (with scope) | 15 | “javascriptWithScope” | |
32-bit integer | 16 | “int” | |
Timestamp | 17 | “timestamp” | |
64-bit integer | 18 | “long” | |
Decimal128 | 19 | “decimal” | New in version 3.4. |
Min key | -1 | “minKey” | |
Max key | 127 | “maxKey” |
$type : number
会匹配4中具体类型
格式
{ field: { $type: <BSON type> } }
{ field: { $type: [ <BSON type1> , <BSON type2>, ... ] } }
示例
单个类型
文档
db.addressBook.insertMany(
[
{ "_id" : 1, address : "2030 Martian Way", zipCode : "90698345" },
{ "_id" : 2, address: "156 Lunar Place", zipCode : 43339374 },
{ "_id" : 3, address : "2324 Pluto Place", zipCode: NumberLong(3921412) },
{ "_id" : 4, address : "55 Saturn Ring" , zipCode : NumberInt(88602117) },
{ "_id" : 5, address : "104 Venus Drive", zipCode : ["834847278", "1893289032"]}
]
)
查询
db.addressBook.find( { "zipCode" : { $type : 2 } } );
db.addressBook.find( { "zipCode" : { $type : "string" } } );
将返回 zipCode 类型是字符串的文档 或 zipCode 类型是数组但包含一个字符串元素的文档
结果
{ "_id" : 1, "address" : "2030 Martian Way", "zipCode" : "90698345" }
{ "_id" : 5, "address" : "104 Venus Drive", "zipCode" : [ "834847278", "1893289032" ] }
多个类型
文档
db.grades.insertMany(
[
{ "_id" : 1, name : "Alice King" , classAverage : 87.333333333333333 },
{ "_id" : 2, name : "Bob Jenkins", classAverage : "83.52" },
{ "_id" : 3, name : "Cathy Hart", classAverage: ["94.06", 10] },
{ "_id" : 4, name : "Drew Williams" , classAverage : NumberInt("93") }
]
)
查询
db.grades.find( { "classAverage" : { $type : [ 2 , 1 ] } } );
db.grades.find( { "classAverage" : { $type : [ "string" , "double" ] } } );
将返回 classAverage 类型是字符串或double类型的文档 或 classAverage 类型是数组但包含一个字符串或double类型的元素
结果
{ "_id" : 1, name : "Alice King" , classAverage : 87.333333333333333 }
{ "_id" : 2, name : "Bob Jenkins", classAverage : "83.52" }
{ "_id" : 3, name : "Cathy Hart", classAverage: ["94.06", 10] }
评估操作符
格式
{ $expr: { <expression> } }
示例
搭配比较聚合表达式
文档
{ "_id" : 1, "category" : "food", "budget": 400, "spent": 450 }
{ "_id" : 2, "category" : "drinks", "budget": 100, "spent": 150 }
{ "_id" : 3, "category" : "clothes", "budget": 100, "spent": 50 }
{ "_id" : 4, "category" : "misc", "budget": 500, "spent": 300 }
{ "_id" : 5, "category" : "travel", "budget": 200, "spent": 650 }
查询
db.monthlyBudget.find( { $expr: { $gt: [ "$spent" , "$budget" ] } } )
$gt 聚合表达式表示,第一个字段的值大于第二个字段的值返回true,否则返回false
结果
{ "_id" : 1, "category" : "food", "budget" : 400, "spent" : 450 }
{ "_id" : 2, "category" : "drinks", "budget" : 100, "spent" : 150 }
{ "_id" : 5, "category" : "travel", "budget" : 200, "spent" : 650 }
验证模式,用来数据校验
使用者必须具有 collMod 权限
https://docs.mongodb.com/v4.2/reference/command/collMod/#collmod
格式
{ field: { $mod: [ divisor, remainder ] } }
示例
文档
{ "_id" : 1, "item" : "abc123", "qty" : 0 }
{ "_id" : 2, "item" : "xyz123", "qty" : 5 }
{ "_id" : 3, "item" : "ijk123", "qty" : 12 }
查询
db.inventory.find( { qty: { $mod: [ 4, 0 ] } } )
查询条件是:qty的值对4取摸余数为0
结果
{ "_id" : 1, "item" : "abc123", "qty" : 0 }
{ "_id" : 3, "item" : "ijk123", "qty" : 12 }
格式
{
$text:
{
$search: <string>,
$language: <string>,
$caseSensitive: <boolean>,
$diacriticSensitive: <boolean>
}
}
$search
类型:字符串
描述:
mongodb 解析并用于查询文本索引的术语字符串
文本操作符将 $search 字符串中的大多数标点符号视为分隔符,但否定术语的连字符-
和 指定短语的转义双引号\" \"
除外
转义双引号
匹配短语,需将短语括在转义双引号\"
中
"\"ssl certificate\""
如果 $search 字符串包含一个短语和单个术语,则文本查询只匹配包含短语的文档
"\"ssl certificate\" authority key"
$text 操作符将只匹配 "ssl certificate"
短语,忽略后面的单个术语 authority key
连字符
$language
$caseSensitive
类型:布尔
描述:查询文本是否区分大小写
false【默认】
不区分
$diacriticSensitive
类型:布尔
描述:查询文本是否区别变音符
false【默认】
不区分
示例
文档
db.articles.createIndex( { subject: "text" } )
db.articles.insert(
[
{ _id: 1, subject: "coffee", author: "xyz", views: 50 },
{ _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 },
{ _id: 3, subject: "Baking a cake", author: "abc", views: 90 },
{ _id: 4, subject: "baking", author: "xyz", views: 100 },
{ _id: 5, subject: "Café Con Leche", author: "abc", views: 200 },
{ _id: 6, subject: "Сырники", author: "jkl", views: 80 },
{ _id: 7, subject: "coffee and cream", author: "efg", views: 10 },
{ _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 }
]
)
查询单个术语
db.articles.find( { $text: { $search: "coffee" } } )
查询用空格分隔的字符串
$text操作符对每个术语执行逻辑或搜索,并返回包含任何术语的文档。
db.articles.find( { $text: { $search: "bake coffee cake" } } )
返回 subject 字段包含 "bake" 或 "coffee" 或 "cake" 的文档
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 }
{ "_id" : 7, "subject" : "coffee and cream", "author" : "efg", "views" : 10 }
{ "_id" : 1, "subject" : "coffee", "author" : "xyz", "views" : 50 }
{ "_id" : 3, "subject" : "Baking a cake", "author" : "abc", "views" : 90 }
{ "_id" : 4, "subject" : "baking", "author" : "xyz", "views" : 100 }
查询短语
db.articles.find( { $text: { $search: "\"coffee shop\"" } } )
返回 subject 字段包含 "coffee shop" 的文档
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 }
否定单词
db.articles.find( { $text: { $search: "coffee -shop" } } )
返回 subject 字段包含 coffee,但不包含 shop 的文档
{ "_id" : 7, "subject" : "coffee and cream", "author" : "efg", "views" : 10 }
{ "_id" : 1, "subject" : "coffee", "author" : "xyz", "views" : 50 }
文档匹配分数
db.articles.find(
{ $text: { $search: "cake" } },
{ score: { $meta: "textScore" } }
)
返回
{ "_id" : 3, "subject" : "Baking a cake", "author" : "abc", "views" : 90, "score" : 0.75 }
在查询语言中使用正则表达式
mongodb 使用 PCRE 正则表达式
格式
正则操作符表达式
{ <field>: { $regex: /pattern/, $options: ‘<options>‘ } }
{ <field>: { $regex: ‘pattern‘, $options: ‘<options>‘ } }
{ <field>: { $regex: /pattern/<options> } }
正则对象表达式
{ <field>: /pattern/<options> }
定界符可以使用 正斜杠 或 单引号
options
类型:字符串,只有省略操作符后可以不加单引号
i
忽略大小写
文档
{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }
{ "_id" : 102, "sku" : "xyz456", "description" : "Many spaces before line" }
{ "_id" : 103, "sku" : "xyz789", "description" : "Multiple\nline description" }
查询
db.products.find( { sku: { $regex: /^ABC/i } } )
匹配结果
{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }
m
对于包含锚点的模式(例如 ^
表示开始,$
表示结束)
文档
{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }
{ "_id" : 102, "sku" : "xyz456", "description" : "Many spaces before line" }
{ "_id" : 103, "sku" : "xyz789", "description" : "Multiple\nline description" }
查询
db.products.find( { description: { $regex: /^S/, $options: ‘m‘ } } )
当数据为多行时,含有\n
,设置 m 选项,则每行都单独匹配,任何一行符合条件即可
匹配结果为
{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }
当数据为多行时,含有\n
,没有设置 m 选项,则按一行进行匹配
匹配结果为
{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }
对于不包含锚点的模式,或字符串没有分行,则按一行进行匹配, 设置 m 选项不起作用
db.products.find( { description: { $regex: /S/ } } )
正则表达式不包含 ^ 或 $
匹配的结果为
{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }
x
忽略空格
使用x选项忽略空格和注释 (在匹配模式中以#开始,以\n结束)
文档
{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }
{ "_id" : 102, "sku" : "xyz456", "description" : "Many spaces before line" }
{ "_id" : 103, "sku" : "xyz789", "description" : "Multiple\nline description" }
查询
var pattern = "abc #category code\n123 #item number"
db.products.find( { sku: { $regex: pattern, $options: "x" } } ) //=> pattern = "abc123"
匹配结果
{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }
s
允许.
匹配所有的字符,包括换行符
当数据为多行时,含有
\n
,将多行视为一行,换行符\n
被视为普通字符
文档
{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }
{ "_id" : 102, "sku" : "xyz456", "description" : "Many spaces before line" }
{ "_id" : 103, "sku" : "xyz789", "description" : "Multiple\nline description" }
查询
db.products.find( { description: { $regex: /m.*line/, $options: ‘si‘ } } )
匹配结果为
{ "_id" : 102, "sku" : "xyz456", "description" : "Many spaces before line" }
{ "_id" : 103, "sku" : "xyz789", "description" : "Multiple\nline description" }
.
匹配换行符,视为一行不设置 s 选项,则匹配结果为
{ "_id" : 102, "sku" : "xyz456", "description" : "Many spaces before line" }
$regex vs. /pattern/ Syntax:{}
在 $in 操作符中,只能使用 JS正则对象表达式
{ name: { $in: [ /^acme/i, /^ack/ ] } }
以逗号分隔的多查询条件列表中,使用 $regex 正则操作符表达式
{ name: { $regex: /acme.*corp/i, $nin: [ ‘acmeblahcorp‘ ] } }
{ name: { $regex: /acme.*corp/, $options: ‘i‘, $nin: [ ‘acmeblahcorp‘ ] } }
{ name: { $regex: ‘acme.*corp‘, $options: ‘i‘, $nin: [ ‘acmeblahcorp‘ ] } }
要使用选项 ixsm,使用 $regex 正则操作符表达式
3.6版本中 $expr 操作符允许在查询语言中使用聚合表达式,比where执行速度更快,因为不执行 JavaScript 代码,应首选 $expr
在查询语言中使用 JavaScript 表达式
使用 $where 操作符将包含 JavaScript表达式的字符串 或 完整的JavaScript函数传递给查询系统
集合中的每个文档都会执行 JavaScript表达式
在 JavaScript 表达式中通过 this 或 obj 引用文档
格式
{ $where: <JavaScript expression>
支持的属性和方法
Available Properties | Available Functions | ||
---|---|---|---|
args | assert() | isNumber() | print() |
MaxKey | BinData() | isObject() | printjson() |
MinKey | DBPointer() | ISODate() | printjsononeline() |
DBRef() | isString() | sleep() | |
doassert() | Map() | Timestamp() | |
emit() | MD5() | tojson() | |
gc() | NumberInt() | tojsononeline() | |
HexData() | NumberLong() | tojsonObject() | |
hex_md5() | ObjectId() | UUID() | |
version() |
示例
文档
{
_id: 12378,
name: "Steve",
username: "steveisawesome",
first_login: "2017-01-01"
}
{
_id: 2,
name: "Anya",
username: "anya",
first_login: "2001-02-02"
}
查询
db.players.find( { $where: function() {
return (hex_md5(this.name) == "9b53e667f30cd329dca1ec9e6a83e994")
} } );
$where 操作符的值是一个函数,集合中的每个文档都会执行该函数
结果
{
"_id" : 2,
"name" : "Anya",
"username" : "anya",
"first_login" : "2001-02-02"
}
格式
{ <field>: { $all: [ <value1> , <value2> ... ] } }
示例
跟 $and 转换
{ tags: { $all: [ "ssl" , "security" ] } }
相当于,分别指定一个 $eq 表达式
{ $and: [ { tags: "ssl" }, { tags: "security" } ] }
格式
{ <field>: { $elemMatch: { <query1>, <query2>, ... } } }
示例
元素匹配
{ _id: 1, results: [ 82, 85, 88 ] }
{ _id: 2, results: [ 75, 88, 89 ] }
查找
db.scores.find(
{ results: { $elemMatch: { $gte: 80, $lt: 85 } } }
)
https://docs.mongodb.com/manual/reference/operator/update-field/
increments 增长
格式
{ $inc: { <field1>: <amount1>, <field2>: <amount2>, ... } }
更改指定字段名
如果 newName 已经存在与文档中,则会将该字段删除,然后再将指定字段名修改为 newName
相当于先对 old name 和 new name 执行 $unset 操作,然后再对 new name 执行 $set 操作
重命名的字段在文档中的顺序可能会改变
如果指定字段不存在,则什么都不做
对于嵌入文档中的字段,$rename操作符可以重命名这些字段,也可以将字段移进或移出嵌入文档。如果这些字段在数组元素中,则$rename不起作用
重命名,则 newName 也需要使用点表示法引用外层文档
db.students.update( { _id: 1 }, { $rename: { "name.first": "name.fname" } } )
移动,则 newName 不需要用点表示法引用外层文档
db.students.update( {_id:1}, { $rename: { "name.first":"fname" } })
将 fname 移动到顶层
格式
{$rename: { <field1>: <newName1>, <field2>: <newName2>, ... } }
示例
文档
db.students.insert([
{
"_id": 1,
"alias": [ "The American Cincinnatus", "The American Fabius" ],
"mobile": "555-555-5555",
"nmae": { "first" : "george", "last" : "washington" }
},
{
"_id": 2,
"alias": [ "My dearest friend" ],
"mobile": "222-222-2222",
"nmae": { "first" : "abigail", "last" : "adams" }
},
{
"_id": 3,
"alias": [ "Amazing grace" ],
"mobile": "111-111-1111",
"nmae": { "first" : "grace", "last" : "hopper" }
}
])
重命名
db.students.updateMany(
{},
{$rename:{nmae:‘name‘}}
)
移动字段
db.students.update(
{_id:1},
{ $rename: { "name.first":"fname" } }
)
将 "name.first" 字段移动到外面,并重命名为 fname
结果为
{
"_id": 1,
"alias": ["The American Cincinnatus", "The American Fabius"],
"mobile": "555-555-5555",
"name": {
"last": "washington"
},
"fname": "george"
}
格式
{ $set: { <field1>: <value1>, ... } }
若指定子文档或数组中的字段,则使用点表示法
数组
指定 contribs 中第三个元素,则表示为 contribs.2
{ ... contribs: [ "Turing machine", "Turing test", "Turingery" ], ... }
子文档
指定 last 字段,则表示为 name.last
指定 number 字段,则表示为 contact.phone.number
{ ... name: { first: "Alan", last: "Turing" }, contact: { phone: { type: "cell", number: "111-222-3333" } }, ... }
示例
文档
{
_id: 100,
sku: "abc123",
quantity: 250,
instock: true,
reorder: false,
details: { model: "14Q2", make: "xyz" },
tags: [ "apparel", "clothing" ],
ratings: [ { by: "ijk", rating: 4 } ]
}
更新操作
db.products.update(
{ _id: 100 },
{ $set:
{
quantity:500,
"details.make":"zzz",
"tags.1": "rain gear",
"ratings.0.rating": 2
}
}
)
格式
{ $unset: { <field1>: "", ... } }
.
位置操作符,代表某个元素的位置(下标)
不需要指明具体的元素下标
当用于更新操作时
$
代表匹配更新条件的第一个元素下标
数组字段必须作为更新条件之一
通过对数组的操作,确定符合数组操作的第一个元素
虽然查询结果返回的是整个文档,但是在执行数组的操作时,会记录第一个符合数组过滤条件的元素
示例
元素类型为普通值时{ "<array>.$" : value } }
db.students.insert([
{ "_id" : 1, "grades" : [ 85, 80, 80 ] },
{ "_id" : 2, "grades" : [ 88, 90, 92 ] },
{ "_id" : 3, "grades" : [ 85, 100, 90 ] }
])
更新
db.students.updateOne(
{ grades: {$gte:89} },
{ $set: { "grades.$" : 89 } }
)
数组字段 grades
作为更新条件之一
通过对数组的操作 {$gte:89},确定符合条件的文档以及第一个符合数组过滤条件的元素
在更新操作中用$
代表符合条件的元素
更新 _id
为1,grades数组中包含 80 的文档,并将符合数组过滤条件的第一个元素值改为 89
第一个文档的grades变为 [85, 82, 80]
元素类型为子文档时{ "array.$.field" : value } }
{
_id: 4,
grades: [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 5 },
{ grade: 85, mean: 85, std: 8 }
]
}
更新
db.students.updateOne(
{ _id: 4, "grades.grade": 85 },
{ $set: { "grades.$.std" : 6 } }
)
New in version 3.6.
multi: true
选项,但是测试不加也可以作用于所有元素格式
db.collection.updateMany(
{ <query conditions> },
{ <update operator>: { "<array>.$[]" : value } }
)
示例
元素类型为普通值时 { "<array>.$[]" : value } }
{ "_id" : 1, "grades" : [ 85, 82, 80 ] }
{ "_id" : 2, "grades" : [ 88, 90, 92 ] }
{ "_id" : 3, "grades" : [ 85, 100, 90 ] }
更新
db.students.update(
{ },
{ $inc: { "grades.$[]": 10 } },
{ multi: true }
)
元素类型为子文档时{ "array.$[].field" : value } }
{
"_id" : 1,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 8 },
{ "grade" : 85, "mean" : 90, "std" : 6 },
{ "grade" : 85, "mean" : 85, "std" : 8 }
]
}
{
"_id" : 2,
"grades" : [
{ "grade" : 90, "mean" : 75, "std" : 8 },
{ "grade" : 87, "mean" : 90, "std" : 5 },
{ "grade" : 85, "mean" : 85, "std" : 6 }
]
}
更新
db.students2.update(
{ },
{ $inc: { "grades.$[].std" : -2 } },
{ multi: true }
)
结合过滤位置操作符
db.students3.insert([
{ "_id" : 1,
"grades" : [
{ type: "quiz", questions: [ 10, 8, 5 ] },
{ type: "quiz", questions: [ 8, 9, 6 ] },
{ type: "hw", questions: [ 5, 4, 3 ] },
{ type: "exam", questions: [ 25, 10, 23, 0 ] },
]
}
])
更新
db.students3.update(
{},
{ $inc: { "grades.$[].questions.$[score]": 2 } },
{ arrayFilters: [ { "score": { $gte: 8 } } ], multi: true}
)
New in version 3.6.
格式
db.collection.updateMany(
{ <query conditions> },
{ <update operator> : { "<array>.$[<identifier>]" : value } },
{ arrayFilters: [ { <identifier>: <condition> } ] }
)
示例
元素类型为普通值时 { "<array>.$[<identifier>]" : value } }
{ "_id" : 1, "grades" : [ 95, 92, 90 ] }
{ "_id" : 2, "grades" : [ 98, 100, 102 ] }
{ "_id" : 3, "grades" : [ 95, 110, 100 ] }
更新
db.students.update(
{ },
{ $set: { "grades.$[element]" : 100 } },
{ multi: true,
arrayFilters: [ { "element": { $gte: 100 } } ]
}
)
元素类型为子文档时{ "array.$[<identifier>].field" : value }
{
"_id" : 1,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 6 },
{ "grade" : 85, "mean" : 90, "std" : 4 },
{ "grade" : 85, "mean" : 85, "std" : 6 }
]
}
{
"_id" : 2,
"grades" : [
{ "grade" : 90, "mean" : 75, "std" : 6 },
{ "grade" : 87, "mean" : 90, "std" : 3 },
{ "grade" : 85, "mean" : 85, "std" : 4 }
]
}
更新
db.students2.update(
{ },
{ $set: { "grades.$[elem].mean" : 100 } },
{
multi: true,
arrayFilters: [ { "elem.grade": { $gte: 85 } } ]
}
)
嵌套数组
db.students3.insert(
{ "_id" : 1,
"grades" : [
{ type: "quiz", questions: [ 10, 8, 5 ] },
{ type: "quiz", questions: [ 8, 9, 6 ] },
{ type: "hw", questions: [ 5, 4, 3 ] },
{ type: "exam", questions: [ 25, 10, 23, 0 ] },
]
}
)
更新
db.students3.update(
{},
{ $inc: { "grades.$[t].questions.$[score]": 2 } },
{ arrayFilters: [ { "t.type": "quiz" } , { "score": { $gte: 8 } } ], multi: true}
)
[ ]
格式
{ $pop: { <field>: <-1 | 1>, ... } }
示例
文档
{ _id: 1, scores: [ 8, 9, 10 ] }
更新
db.students.update( { _id: 1 }, { $pop: { scores: -1 } } )
删除第一个元素
结果为
{ _id: 1, scores: [ 9, 10 ] }
删除数组中指定的值 或 所有符合条件的值
如果指定了 condition,且数组元素是嵌套文档,$pull 操作符会将每个嵌套子文档视为顶级文档进行 condition 匹配
如果指定的值 value 是数组,则 $pull 操作符将删除与 value 完全匹配的元素,包括元素顺序
如果指定的值 value 是文档,则 $pull 操作符将删除与 value 具有相同字段和值的元素,忽略字段顺序
格式
{ $pull: { <field1>: <value|condition>, <field2>: <value|condition>, ... } }
示例
删除指定值
db.stores.update(
{ },
{ $pull: { fruits: { $in: [ "apples", "oranges" ] }, vegetables: "carrots" } },
{ multi: true }
)
删除满足条件的值
db.profiles.update( { _id: 1 }, { $pull: { votes: { $gte: 6 } } } )
两层嵌套:数组元素是子文档
{
_id: 1,
results: [
{ item: "A", score: 5 },
{ item: "B", score: 8, comment: "Strongly agree" }
]
}
{
_id: 2,
results: [
{ item: "C", score: 8, comment: "Strongly agree" },
{ item: "B", score: 4 }
]
}
更新
db.survey.update(
{ },
{ $pull: { results: { score: 8 , item: "B" } } },
{ multi: true }
)
condition 为 子文档 { score: 8 , item: "B" }
不需要通过 $elemMatch 指定
db.survey.update(
{ },
{ $pull: { results: { $elemMatch: { score: 8 , item: "B" } } } },
{ multi: true }
)
不会删除任何元素
三层嵌套:数组元素是子文档,子文档字段是数组
{
_id: 1,
results: [
{ item: "A", score: 5, answers: [ { q: 1, a: 4 }, { q: 2, a: 6 } ] },
{ item: "B", score: 8, answers: [ { q: 1, a: 8 }, { q: 2, a: 9 } ] }
]
}
{
_id: 2,
results: [
{ item: "C", score: 8, answers: [ { q: 1, a: 8 }, { q: 2, a: 7 } ] },
{ item: "B", score: 4, answers: [ { q: 1, a: 0 }, { q: 2, a: 8 } ] }
]
}
更新
db.survey.update(
{ },
{ $pull: { results: { answers: { $elemMatch: { q: 2, a: { $gte: 8 } } } } } },
{ multi: true }
)
格式
{ $push: { <field1>: <value1>, ... } }
结合修饰符
{ $push: { <field1>: { <modifier1>: <value1>, ... }, ... } }
示例
结合 $each 修饰符,将数组中的元素分别添加到指定字段
db.students.update(
{ name: "joe" },
{ $push: { scores: { $each: [ 90, 92, 85 ] } } }
)
结合 $each $sort $slice
{
"_id" : 5,
"quizzes" : [
{ "wk": 1, "score" : 10 },
{ "wk": 2, "score" : 8 },
{ "wk": 3, "score" : 5 },
{ "wk": 4, "score" : 6 }
]
}
更新
db.students.update(
{ _id: 5 },
{
$push: {
quizzes: {
$each: [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ],
$sort: { score: -1 },
$slice: 3
}
}
}
)
$each
将数组 [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ] 中的元素分别添加到 quizzes 数组中
$sort
将数组中的所有元素按照 score 字段的值降序排列
$slice
提出数组中前3个元素
原文:https://www.cnblogs.com/usmile/p/13576779.html