基础查询
正则查询
{status: 'A',$or: [{ qty: { $lt: 30 } }, { item: { $regex: '^p' } }]
}
AND 查询
{ "size.h": { $lt: 15 }, "size.uom": "in", status: "D" }
OR 查询
{ $or: [ { status: "A" }, { qty: { $lt: 30 } } ] }
AND 和 OR 混合
{ status: "A", $or: [ { qty: { $lt: 30 } }, { item: /^p/ } ] }
嵌套对象查询
用点号来查询嵌套字段
这种方式写的带点号的字段必须包含在双引号之中
{ "size.h": { $lt: 15 } }
{ "size.uom": "in" }
匹配嵌套文档对象
注意❗这种查询方式是字段顺序相关的,也就是说:
{item: 'journal',qty: 25,size: { h: 14, w: 21, uom: 'cm' },status: 'A'
},// 查得到数据
{ size: { h: 14, w: 21, uom: "cm" } }// 查不到数据
{ size: { w: 21, h: 14, uom: "cm" } }
数组查询
数组类型的匹配查询时,也是顺序相关的
{ tags: ["red", "blank"] }
// 查询到不一样的结果
{ tags: ["blank", "red"] }
查询一个数组值中包含指定的复数成员, 顺序无关
{ tags: { $all: ["red", "blank"] } }
查询一个数组中是否至少包含一个指定的成员
// tags 是一个数组,查询是否有成员 red
{ tags: "red" }
查询文档中所有记录的 dim_cm
数组,获取其中至少有一个成员值大于 25 的记录
{ dim_cm: { $gt: 25 } }
比较特殊的样例, 当数组值查询时, 数组中任一成员满足其中一个条件,就会被认定为符合条件
{ dim_cm: { $gt: 15, $lt: 20 } }
比如这一条,只要 dim_cm
中有成员值大于 15 或者小于 20,本条记录就会被返回。而不是直觉上的同时满足大于 15 和小于 20
使用 $elemMatch
来完成复数条件查询
上面的反例,想要查询任一成员同时满足多个条件的数组时,需要用 $elemMatch
{ dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } }
对比刚刚的查询,结果数变少了
对固定位置的元素进行查询
使用前面嵌套字段查询提到的 .
操作符,可以对数组字段中指定位置的元素值进行查询
{ "dim_cm.1": { $gt: 25 } }
指定数组的长度条件
查询 tags
的成员数等于 3 的记录
{ "tags": { $size: 3 } }
对象数组的查询
成员值完全匹配查询
查询成员字段 warehouse = ‘A’ 和 qty = 5 的记录,顺序相关
{ "instock": { warehouse: "A", qty: 5 } }
对成员中的某个字段查询
.
操作符的使用
查询 instock 成员中 qty >= 20 的记录
{ 'instock.qty': { $lte: 20 } }
对固定位置的成员进行查询
{ 'instock.0.qty': { $gt: 10, $lte: 20 } }
查询至少一个成员满足复数条件的文档
使用 $elemMatch
可以进行复数条件查询,顺序无关。前面没有使用 $elemMatch
就是值查询,是顺序相关的。
{ "instock": { $elemMatch: { qty: 5, warehouse: "A" } } }
查询成员满足任意条件的文档
会查出有成员 qty > 10 或者 qty <= 20 的文档
{ "instock.qty": { $gt: 10, $lte: 20 } }
另一个样例:
这里也是只要有成员满足这两个条件之一,这条记录就会被查到,不必要有一个成员同时满足两个条件。
{ "instock.qty": 5, "instock.warehouse": "A" }
查询成员字段同时满足多个条件
这个例子官方文档没有提到, 和上面的对比是现在至少一个成员的 qty 值要同时满足两个条件才会被查到
{ "instock": { $elemMatch: { qty: { $gt: 10, $lte: 20 } } } }
总结一下的点操作符用到的场景
- 嵌套对象字段查询
{ "size.h": { $lt: 15 } }
{ "size.uom": "in" }
- 数组固定位置的元素进行查询
{ "dim_cm.1": { $gt: 25 } }
- 对象数组中对成员字段进行查询
{ 'instock.qty': { $lte: 20 } }
- 对象数组中对固定位置的成员进行查询
{ 'instock.0.qty': { $gt: 10, $lte: 20 } }
Project 返回你想要的字段
基础使用
在填写 project 的地方传入下面的对象,返回的记录中就只会有 item
,status
和一个默认的 _id
字段
{ item: 1, status: 1 }
删除 _id
不想要 _id
就在 project 里面给个 0 值就行
{ item: 1, status: 1, _id: 0 }
上面的语句同时使用了 1
来标记需要展示字段,和 0
来删除 _id
,这种用法仅限于 _id
字段
仅删除不需要的字段
有时需要显示的字段很多,不需要的很少,可以仅用 0
删除不需要的字段。
{ status: 0, instock: 0 }
嵌套对象的 Project
就用前面学到的 .
操作符就好了
{ item: 1, status: 1, "size.uom": 1 }
仅删除不要字段也是给个 0
就行
{ "size.uom": 0 }
对象数组中的 Project
返回结果的 instock 数组成员仅有 qty 字段
{ item: 1, status: 1, "instock.qty": 1 }
数组元素的 Project
- $elemMatch
对数组元素的 Project 会复杂一些,官方提供了三种操作:
$elemMatch
, $slice
, $
首先是前面见得比较多的 $elemMatch
, 当这个从操作出现在 Project 里面时,就是对数组字段的成员进行筛选,返回符合条件第一个成员。
{"students": { $elemMatch: { age: { $gte: 10, $lte: 20 } } }}
- $slice
对数组成员进行切片,三种语法
$slice: 正数
返回数组的前 2 个成员
{"students": { $slice: 2 }}
$slice: 负数
返回数组的后 2 个成员
{"students": { $slice: -2 }}
$slice: [n, m]
先跳过数组的前 n 个成员,再返回 m 个成员
{"students": {$slice: [1, 2]}}
$
这个符号需要在查询时有对数组字段附加了查询条件,这样就可以在 Project 时用这个符号来返回符合查询条件的第一个成员
query: {zipcode: "63109", "students.age": { $gt: 10 }}
project: {"students.$": 1}
管道 Aggregation (持续更新,创作中)
管道可以说是 MongoDB 最核心的东西了。
$unwind
对一个数组字段 $unwind, 就会将数组的每个成员当成输入,然后根据情况不断替换原来的数组字段,并产生一个新的文档
举例:
{ "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] }
对 sizes 进行 $unwind
db.inventory.aggregate( [ { $unwind : "$sizes" } ] )
得到结果:
原本的数组成员被展开了,分别替换原来的数组字段形成新的文档
{ "_id" : 1, "item" : "ABC1", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "L" }