mongodb之查询操作
在上一篇mongodb之remove操作操作中详细介绍了常用的字段更新操作符,工作中最常用的就是mongodb中各种复杂的查询,在关系型数据库中,可以实现基于表的各种各样的查询,以及通过投影来返回指定的列,相应的查询功能也可以在 MongoDB 中实现。同时由于 MongoDB 支持嵌套文档和数组,MongoDB 也可以实现基于嵌套文档和数组的查询,下面我们详细介绍mongodb中功能丰富的查询。
1. find
说明:
选择集合中的文档,并按照查询条件返回到所选文档。
语法:
db.collection.find(
<query>,
<projection>
)
备注:
query格式 :{ field1: <value>, field2: <value> ... }
参数讲解;
query:可选的。使用查询操作符指定选择筛选器,相当于读取文档筛选文档的条件。若要返回集合中的所有文档,请省略此参数或传递一个空文档({})。
projection:可选的。指定要在文档中返回与查询筛选器匹配的字段,相当于指定返回哪些字段。要返回匹配文档中的所有字段,请省略此参数。有关详细信息,请参见投影。
1.1. 常用操作符
1.1.1. 比较查询操作符
$eq:匹配等于指定值的值。
$ne:匹配不等于指定值的所有值。
$in:匹配数组中指定的任何值。
$nin:不匹配数组中指定的值。
$gt:匹配大于指定值的值。
$gte:匹配大于或等于指定值的值。
$lt:匹配小于指定值的值。
$lte:匹配小于或等于指定值的值。
1.1.2. 逻辑查询操作符
$and:将查询子句与逻辑连接,并返回与这两个子句条件匹配的所有文档,相当于匹配多个筛选条件全部成立的文档。
$nor:用逻辑NOR连接查询子句,返回所有不能匹配这两个子句的文档,相当于返回多个筛选条件全部不成立的文档。
$or:用逻辑连接查询子句,或返回与任一子句条件匹配的所有文档,相当于返回至少一个筛选条件成立的文档
$not:反转查询表达式的效果,并返回与查询表达式不匹配的文档,相当于返回条件不成立的文档。
1.1.3. 元素查询操作符
$exists:匹配具有指定字段的文档。
$type:如果字段属于指定类型,则选择文档。
1.1.4. 评估查询操作符
$expr:允许在查询语言中使用聚合表达式。
$regex:选择值匹配指定正则表达式的文档。
1.1.5. 数组查询操作符
$all:匹配包含查询中指定的所有元素的数组,相当于返回数组字段中包含所有查询值的文档。
$elemMatch:如果数组字段中的元素匹配所有指定的$elemMatch条件,则选择文档,相当于匹配数组字段中至少存在一个值满足筛选条件的文档
$size:如果数组字段是指定大小,则选择文档。
1.2. 示例
示例:
初始化数据:
db.findExample.insertMany([
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A",tags: ["blank", "red"], dim_cm: [ 14, 21 ],instock: [ { warehouse: "A", qty: 5 }, { warehouse: "C", qty: 15 } ] },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A", tags: ["red", "blank"], dim_cm: [ 14, 21 ] , instock: [ { warehouse: "C", qty: 5 } ] },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D", tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ], instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 15 } ]},
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" , tags: ["blank", "red"], dim_cm: [ 22.85, 30 ], instock: [ { warehouse: "A", qty: 40 }, { warehouse: "B", qty: 5 } ] },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" , tags: ["blue"], dim_cm: [ 10, 15.25 ], instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }
]);
1.2.1. 查询单个对象
1.2.1.1. 查询全部
db.findExample.find({})
1.2.1.2. 根据某个字段相等查询
db.findExample.find({status:"D"})
1.2.1.3. 根据某个字段in查询
db.findExample.find({ status: { $in: [ "A", "D" ] } } )
1.2.1.4. 根据多个字段查询
【注意,MongoDB 查询过程中,在没有其它限定条件,比如$or的情况下,两个相邻的条件自动的被翻译为 AND 操作,相当于隐式AND操作】
db.findExample.find( { status: "A", qty: { $lt: 30 } } )
1.2.1.5. 根据多个字段查询显式AND操作
db.findExample.find( { $and: [ { status: "A" }, { qty: { $lt: 30 } } ] } )
1.2.1.6. 根据多个字段or查询
db.findExample.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )
1.2.1.7. 隐式AND加OR查询
db.findExample.find( {
status: "A",
$or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
} )
1.2.2. 查询(单个)嵌入式文档
1.2.2.1. 内嵌文档完整匹配
【注意:匹配嵌入式文档的字段名的顺序不能颠倒】
db.findExample.find( { size: { h: 14, w: 21, uom: "cm" } })
1.2.2.2. 在内嵌文档字段上使用相等查询
db.findExample.find( { "size.uom": "in" } )
1.2.3. 查询(多个)嵌入式文档
1.2.3.1. 内嵌文档完整匹配
【注意:只要多个内嵌 documents 中只要有一个完全匹配了上述的查询条件,则将会返回该 document,字段名的顺序不能乱,元素不能少】
db.findExample.find( { "instock": { warehouse: "A", qty: 5 } } )
1.2.3.2. 根据对象坐标定位元素进行查询
db.findExample.find( { 'instock.0.qty': { $lte: 10 } } )
1.2.3.3. 根据多个过滤条件以 OR 的方式进行查询
db.findExample.find( { "instock.qty": 5, "instock.warehouse": "A" } )
1.2.3.4. 根据多个过滤条件以 AND 的方式进行查询
db.findExample.find( { "instock": { $elemMatch: { qty: 5, warehouse: "A" } } } )
1.2.4. 查询数组
1.2.4.1. 数组精确匹配查询
db.findExample.find( { tags: ["red", "blank"] } )
1.2.4.2. 部分匹配(包含关系,相当于in,与顺序无关)
db.findExample.find( { tags: { $all: ["red", "blank"] } } )
1.2.4.3. 查询数组包含了某一个元素
db.findExample.find( { tags: "plain" } )
1.2.4.4. 数组中使用单个操作符号
【$gt 大于 $gte 大于等于 $lt小于 $lte 小于等于】
db.findExample.find( { dim_cm: { $gt: 25 } } )
1.2.4.5. 数组中使用多个操作符号
【复合过滤条件其实执行的是OR的关系查询,只要队列中有某一个元素满足其中的一个条件既算是该 document 匹配了】
db.findExample.find( { dim_cm: { $gt: 15, $lt: 20 } }
1.2.4.6. 根据数组坐标定位元素进行查询
db.findExample.find( { "dim_cm.1": { $gt: 25 } } )
1.2.4.7. 通过队列的长度进行匹配查询
db.findExample.find( { "tags": { $size: 3 } } )
1.2.5. 限定返回字段
【注意:默认输出的字段 _id】
db.findExample.find( { status: "A" }, { item: 1, status: 1 } )
【注意:不输出的字段 _id】
db.findExample.find( { status: "A" }, { item: 1, status: 1, _id: 0 } )
指定不返回的字段集【该查询将会返回所有的结果字段除了 status 和 instock;】
db.findExample.find( { status: "A" }, { status: 0, instock: 0 } )
限定嵌入文档的返回字段集
返回嵌入文档中的指定字段集
db.findExample.find( { status: "A" }, { item: 1, status: 1, "instock.qty": 1 } )
通过限定操作符来限定返回字段集
以 $slice 为例,下面的这个例子只会返回 instock 内嵌文档集合中的最后一个元素;
db.findExample.find( { status: "A" }, { name: 1, status: 1, instock: { $slice: -1} } )
1.2.6. 查询空值或缺失字段
初始化测试数据
db.findNullExample.insertMany([
{ _id: 1, item: null },
{ _id: 2 }
])
【使用{ item : null }来匹配 documents,将会匹配两种情况,1、包含 item 字段且 item 值为 null;2、不包含 item 字段;】
db.findNullExample.find( { item: null } )
另外,还可以使用 BSON Type 的方式来进行匹配,使用 { item : { $type: 10 } },其中,{ $type: 10 }表示的是 BSON Type Null;使用 BSON Type Null 来进行查询,只会匹配某个文档,包含此 item 字段,且其值为 null;
db.findNullExample.find( { item : { $type: 10 } } )
匹配字段是否存在
db.findNullExample.find( { item : { $exists: false } } )
2. findOne
说明:
返回满足集合或视图上指定查询条件的文档。如果多个文档满足查询,该方法根据自然顺序返回第一个文档,自然顺序反映了磁盘上文档的顺序。在capped集合中,自然顺序与插入顺序相同。如果没有文档满足查询,该方法返回null。
语法及使用方法同find一致