##Mongodb查询语法
一.查询文档
本段提供了使用 mongo shell中 db.collection.find() 方法查询的案例。案例中使用的 inventory 集合数据可以通过下面的语句产生。
db.inventory.insertMany([   
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },   
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },   
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },   
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },   
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }]);

1.1 检索集合中的所有文档
db.inventory.find( {} )

1.2 等值查询

在查询过滤文档中使用 **<字段>:<值>** 表达式实现等值查询:
{ <field1>: <value1>, ... }

返回 inventory 集合中 status 等于 " D "** 的所有文档:
db.inventory.find( { status: "D" } )

1.3 查询条件中使用的操作符

查询过滤文档中可以使用查询操作符来指定多个条件,格式如下:
{ <field1>: { <operator1>: <value1> }, ... }

集合中 status 等于 " A " 或 " D " 的所有文档 。
db.inventory.find( { status: { $in: [ "A", "D" ] } } )

1.4 AND 条件

返回 inventory 集合中 status 等于 " A "  并且 qty小于($lt)30 的所有文档:
db.inventory.find( { status: "A", qty: { $lt: 30 } } )

关于 MongoDB 的比较操作符可以参考比较操作符。

1.5 OR 条件

下面的案例返回 inventory 集合中 status 等于 "A" 或者 qty小于 ($lt)30 的所有文档。
db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )

1.6 同时使用 AND 和 OR 条件

下面的案例返回 inventory 集合中 status 等于 "A" 并且 qty 小于 ($lt) 30 或者 item 是以 p 字符开头的所有文档。
db.inventory.find( {     status: "A",     $or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]} )

上述操作对应如下 SQL :
SELECT * FROM inventory WHERE status = "A" AND ( qty < 30 OR item LIKE "p%")


二.查询嵌套文档

本段提供了使用 mongo shell 中 db.collection.find() 方法查询嵌套文档的操作案例。案例中使用的 inventory 集合数据可以通过下面的语句产生。
db.inventory.insertMany( [
   { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
   { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },   
   { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },   
   { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },   
   { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }]);

对嵌套文档的字段做等值查询的时候,使用query filter document {:} 其中 **** 是等值匹配的文档。

--嵌套文档中的完全匹配,必须要顺序一致
返回 inventory 集合中 size 字段的值等于{ h: 14, w: 21, uom: "cm" } 的所有文档。
db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } } )
--顺序不一致,则查询不到数据
db.inventory.find(  { size: { w: 21, h: 14, uom: "cm" } }  )

2.1嵌套文档中的字段等值查询

下面的案例返回 inventory 集合中 size 字段中嵌套文档字段 uom 值等于 **"in"** 的所有文档。
db.inventory.find( { "size.uom": "in" } )

2.2 使用查询操作符查询

在 query filter document 中可以使用查询操作符指定多个查询条件,格式如下:
{ <field1>: { <operator1>: <value1> }, ... }

下面的查询语句在字段 size 中的嵌套文档字段 h 上面使用 ($lt) 操作符:
db.inventory.find( { "size.h": { $lt: 15 } } )
db.inventory.find( { "size.h": { $gt: 10 , $lt: 15} } )

2.3 使用 AND 条件

下面的案例返回 inventory 集合中 size 字段中嵌套文档字段 h 值小于15 并且 size 字段中嵌套文档字段 uom 值等于 **"in"** 并且 status 字段等于 **"D"** 的所有文档。
db.inventory.find( { "size.h": { $lt: 15 }, "size.uom": "in", status: "D" } )

三.查询数组
本段提供了使用 mongo shell 中 db.collection.find() 方法查询数组的操作案例。案例中使用的 inventory 集合数据可以通过下面的语句产生。
db.inventory.insertMany([
   { item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
   { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },   
   { item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },   
   { item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },   
   { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }]);

数组字段做等值查询的时候,使用查询文档 **{:}** 其中 **** 是要精确匹配的数组,包含元素的顺序。

--顺序返回,完全匹配
返回 inventory 集合中数组字段 tags 值是只包含两个元素 "red","blank" 并且有指定顺序的数组的所有文档:
db.inventory.find( { tags: ["red", "blank"] } )
--无序,包含两个元素
如果想检索数组中包含 **"red" , "blank"** 两个元素并且不在乎元素顺序或者数组中是否有其它元素。可以使用 $all 操作符:
db.inventory.find( { tags: { $all: ["red", "blank"] } } )

3.1 查询数组中的元素

检索数组字段中至少一个元素等于指定的值,使用 **: 的形式,其中 ** 是一个元素值。
返回 inventory 集合中数组字段 tags 中有一个元素的值是 **"red"** 的所有文档:
db.inventory.find( { tags: "red" } )

对数组中的元素进行检索的时候,可以使用查询操作符在查询过滤文档中。
{ <array field>: { <operator1>: <value1>, ... } }

下面的案例返回 inventory 集合中数组字段 dim_cm 中最少有一个元素的值大于25的所有文档。
db.inventory.find( { dim_cm: { $gt: 25 } } )

3.2 多条件查询数组中的元素

使用多条件查询数组中的元素时,可以在查询语句中指定单个数组元素满足所有查询条件还是多个数组中的元素联合满足所有条件。

3.3 使用多条件查询数组中的元素

返回inventory集合中数组字段dim_cm中单个元素同时满足大于15并且小于20,或者一个元素满足大于15,另外一个元素小于20的所有文档:
db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } )

3.4 数组中的元素同时满足多个查询条件

使用 $elemMatch 来指定多个查询条件在数组中的元素上,数组中最少一个元素同时满足所有的查询条件。

下面的案例返回数组字段 dim_cm 中最少一个元素同时满足大于 ($gt)22 并且 小于 ($lt) 30 :
db.inventory.find( { dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } } )

3.5 使用数组下标查询数组中的元素

使用点号,可以为数组中指定下标的元素指定查询条件,数组下标从0开始。
Note:
当使用点号的时候,字段和嵌套文档字段必须在引号内

下面的案例返回数组字段 dim_cm 中第二个元素大于25的所有文档:
db.inventory.find( { "dim_cm.1": { $gt: 25 } } )

3.6 使用数组长度来检索

使用 $size 操作符通过数组中的元素个数来进行检索。下面的查询返回数组字段 tags 中有三个元素的所有文档 :
db.inventory.find( { "tags": { $size: 3 } } )


四.查询数组中的嵌套文档

本段提供了使用 mongo shell 中的 db.collection.find() 方法对数组中嵌套文档进行查询操作的示例。可以通过下面的语句生成本文使用的 inventory 集合。
db.inventory.insertMany( [
   { item: "journal", instock: [ { warehouse: "A", qty: 5 }, { warehouse: "C", qty: 15 } ] },   
   { item: "notebook", instock: [ { warehouse: "C", qty: 5 } ] },   
   { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 15 } ] },   
   { item: "planner", instock: [ { warehouse: "A", qty: 40 }, { warehouse: "B", qty: 5 } ] },   
   { item: "postcard", instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }]);

4.1 查询数组中的嵌套文档
--完全匹配,顺序相同
返回 instock 数组中元素等于指定文档的的所有文档:
db.inventory.find( { "instock": { warehouse: "A", qty: 5 } } )

当对整个嵌套文档使用等值匹配的时候是要求精确匹配指定文档,包括字段顺序。比如,下面的语句并没有查询到 inventory 集合中的任何文档:
db.inventory.find( { "instock": { qty: 5, warehouse: "A" } } )

4.2 指定查询条件在数组嵌套文档的字段上

下面的案例返回 instock 数组中最少有一个嵌套文档包含字段 qty 的值小于等于20的所有文档 :
db.inventory.find( { 'instock.qty': { $lte: 20 } } )

使用数组下标查询数组中嵌套文档中的字段

使用 dot notation ,可以指定查询条件在数组中指定数组下标的嵌套文档的字段上面。数组下标从0开始。
Note:
当查询使用点号的时候,字段和索引必须在引号内。

下面案例返回 instock 数组中的第一个元素是包含字段 qty 小于等于20的文档的所有文档:
db.inventory.find( { 'instock.0.qty': { $lte: 20 } } )

4.3 指定多个条件检索数组嵌套文档

当对数组中嵌套文档中多个字段指定查询条件的时候,可以在查询语句中指定单个文档满足这些查询条件或者是数组中多个文档联合(单个文档)满足这些查询条件。

单个嵌套文档中的字段满足多个查询条件

使用 $elemMatch 操作符为数组中的嵌套文档指定多个查询条件,最少一个嵌套文档同时满足所有的查询条件。

下面的案例返回 instock 数组中最少有一个嵌套文档包含 qty 等于5同时 warhouse 等于 A 的所有文档:
db.inventory.find( { "instock": { $elemMatch: { qty: 5, warehouse: "A" } } } )

下面的案例返回instock数组中最少一个嵌套文档包含字段qty大于10并且小于20的所有文档:
我们的出发点是instock满足某某条件,而instock是一个数组。在没有$elemMatch的情况下,就会认为任何一个数组元素满足条件都算作instock满足。所以可以用一个元素满足一个条件,另一个元素满足另一个条件

db.inventory.find( { "instock": { $elemMatch: { qty: { $gt: 10, $lte: 20 } } } } )


多个元素联合满足查询条件

如果数组字段上的联合查询条件没有使用 $elemMatch 运算符,查询返回数组字段中多个元素联合满足所有的查询条件的所有文档。

下面的案例返回数组字段 instock 中嵌套文档中 qty 字段大于10并且数组中其它嵌套文档(不一定是同一个嵌套文档) qty 字段小于等于20的所有文档:
db.iventory.find( { "instock.qty": { $gt: 10,  $lte: 20 } } )

下面的案例返回数组字段 instock 中最少一个嵌套文档包含 qty 等于5并且最少一个嵌套文档(不一定是同一个嵌套文档)包含 warehouse 字段等于 A 的所有文档:
db.inventory.find( { "instock.qty": 5, "instock.warehouse": "A" } )

五.查询返回的字段

默认情况下,MongoDB 的查询语句返回匹配到文档的所有字段,为了限制 MongoDB 返回给应用的数据,可以通过 projection 文档来指定或限制返回的字段。

本段提供了使用 mongo shell 中 db.collection.find() 方法映射查询的案例。案例中使用的 inventory 集合数据可以通过下面的语句产生。
db.inventory.insertMany( [
  { item: "journal", status: "A", size: { h: 14, w: 21, uom: "cm" }, instock: [ { warehouse: "A", qty: 5 } ] },  
  { item: "notebook", status: "A",  size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "C", qty: 5 } ] },  
  { item: "paper", status: "D", size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "A", qty: 60 } ] },  
  { item: "planner", status: "D", size: { h: 22.85, w: 30, uom: "cm" }, instock: [ { warehouse: "A", qty: 40 } ] },  
  { item: "postcard", status: "A", size: { h: 10, w: 15.25, uom: "cm" }, instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }]);

5.1 返回匹配文档中的所有字段

如果没有特别指定 projection ,  db.collection.find() 方法将会返回匹配文档的所有字段。
下面的案例返回 inventory 集合中 status 等于 **"A"** 的文档的所有字段。
db.inventory.find( { status: "A" } )

上述操作等价于下面的标准 SQL :
SELECT * from inventory WHERE status = "A"

5.2仅返回指定字段和_id字段

映射会返回在映射文档中显示设置为1的字段。下面的案例返回所有检索到文档中 item, status, _id 三个字段。
db.inventory.find( { status: "A" }, { item: 1, status: 1 } )

上述操作等价于下面的标准 SQL:
SELECT _id, item, status from inventory WHERE status = "A"

5.3 去除 _id 字段

可以通过在映射文档中将 **_id 字段设置为 0** 来从结果集中去除  _id 字段,就像下面的例子: 
db.inventory.find( { status: "A" }, { item: 1, status: 1, _id: 0 } )

上述操作等价于下面的标准 SQL :
SELECT item, status from inventory WHERE status = "A"
Note:
除_id字段外,不能在映射文档中同时使用包含和去除语句。

5.4 去除指定字段

可以使用映射来排除特定字段,而不是在匹配文档中列出要返回的字段。下面的案例返回匹配文档中除 status 和 instock 字段之外的所有字段:
db.inventory.find( { status: "A" }, { status: 0, instock: 0 } )
Note:
除_id字段外,不能在映射文档中同时使用包含和去除语句。

5.5 返回嵌套文档中的指定字段

通过点号引用嵌套文档字段并且在映射文档中将该字段设置为1来实现返回嵌套文档中的指定字段。

下面的案例返回:

_id 字段(默认返回)
item 字段
status 字段
文档 size 中的 uom 字段
uom 字段是 size 嵌套文档中的字段.
db.inventory.find(   { status: "A" },
   { item: 1, status: 1, "size.uom": 1 })

5.6 去除嵌套文档中的指定字段

通过点号引用嵌套文档字段并且在映射文档中将该字段设置为0来实现去除嵌套文档中的指定字段。下面的案例返回匹配文档中除嵌套文档 size 中的 uom 字段外的所有字段。
db.inventory.find(  { status: "A" },  { "size.uom": 0 })

5.7 映射数组中的嵌套文档的指定字段

通过使用点号来映射数组中嵌套文档的指定字段。

下面案例返回:

_id 字段(默认返回)
item 字段
status 字段
数组字段 instock 中的嵌套文档中的 qty 字段
db.inventory.find( { status: "A" },
 { item: 1, status: 1, "instock.qty": 1 } )

5.8 映射返回数组中指定的数组元素

对于数组字段,MongoDB 提供了以下用于操作数组的映射运算符: $elemMatch , $slice , $。

下面的案例使用 $slice 映射操作符返回数组字段 instock 中最后的元素:
db.inventory.find( { status: "A" },
 { item: 1, status: 1, instock: { $slice: -1 } } )

$elemMatch , $slice , $ 是将指定元素映射到返回数组中的唯一方法。

举个例子,不能使用数组下标来映射指定的数组元素。例如: **{ "instock.0": 1 }** 映射不会用第一个元素来映射数组。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐