跳到主要内容

MongoDB 查询

db.collectionName.find(query, projection)
  • query :可选,使用查询操作符指定查询条件
  • projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值,只需省略该参数即可(默认省略)

const cursor = db.collection('inventory').find({ status: 'D' });

若要以易读的方式读取数据,可以用 pretty()

db.collectionName.find().pretty()

使用投影返回特定的字段

选择集合中的所有文档

将空文档作为查询过滤器参数传递给 find 方法

db.collectionName.find( {} )

对应于

SELECT * FROM collectionName

仅返回指定的字段(和 _id 字段)

将投影文档中的 <field> 设置为 1

db.collectionName.find( { status: "A" }, { item: 1, status: 1 } )

对应于

SELECT _id, item, status from collectionName WHERE status = "A"

_id 默认是始终返回的;若要禁止返回默认的 _id,添加 _id: 0

db.collectionName.find( { status: "A" }, { item: 1, status: 1, _id: 0 } )

返回除了被排除的字段之外的所有字段

可以使用 projection 来排除特定的字段,而不是列出要在匹配的文档中返回的字段

db.collectionName.find( { status: "A" }, { status: 0, instock: 0 } )

_id 字段之外,无法在投影文档中同时使用包含 1 与排除 0 声明。

返回嵌入式文档的特定字段

使用 . 返回嵌入式文档中的特定字段

以下示例将返回:

  • _id (默认返回)、itemstatussize 中的 uom 字段(仍会嵌入在 size 文档中)
const cursor = db
.collection('inventory')
.find({
status: 'A'
})
.project({ item: 1, status: 1, 'size.uom': 1 });

您还可以使用嵌套表单指定嵌入式字段。例如:{ item: 1, status: 1, size: { uom: 1 } }

排除语法也是类似,形如 { 'size.uom': 0 }{ size: { uom: 0 } }

对数组中的嵌入式文档的操作也类似,形如 { 'instock.qty': 1 }

对数组元素的指定返回操作

对于包含数组的字段,MongoDB 提供了用来操作数组的以下投影操作符:$elemMatch$slice$

如下示例使用 $slice 投影操作符返回 instock 数组中的最后一个元素:

const cursor = db
.collection('inventory')
.find({
status: 'A'
})
.project({ item: 1, status: 1, instock: { $slice: -1 } });

比较操作符

操作格式范例RDBMS 中的类似语句
等于{<key>:<value>}db.col.find({"name":"Loulou"})where by = 'name'
小于{<key>:{$lt:<value>}}db.col.find({"likes":{$lt:50}})where likes < 50
小于或等于{<key>:{$lte:<value>}}db.col.find({"likes":{$lte:50}})where likes <= 50
大于{<key>:{$gt:<value>}}db.col.find({"likes":{$gt:50}})where likes > 50
大于或等于{<key>:{$gte:<value>}}db.col.find({"likes":{$gte:50}})where likes >= 50
不等于{<key>:{$ne:<value>}}db.col.find({"likes":{$ne:50}})where likes != 50
  • AND 条件:条件间以逗号隔开即可
  • OR 条件:使用关键字 $or

例子

db.inventory.find( { status: "D" } )
db.inventory.find( { status: { $in: [ "A", "D" ] } } )
db.inventory.find( { status: "A", qty: { $lt: 30 } } )
db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )
db.inventory.find( {
status: "A",
$or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
} )

$type 操作符

类型数字备注
Double1
String2
Object3
Array4
Binary data5
Undefined6已废弃。
Object id7
Boolean8
Date9
Null10
Regular Expression11
JavaScript13
Symbol14
JavaScript (with scope)15
32-bit integer16
Timestamp17
64-bit integer18
Min key255Query with -1.
Max key127
db.collection.find({"title": {$type: 2}})

查询数组

有例

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 ] }
]);

查询指定数组匹配的文档

使用查询文档 {<field>:<value>},其中 value 为要匹配的精确数组(元素顺序也要一致)

db.inventory.find( { tags: ["red", "blank"] } )

查询包含指定元素的数组匹配的文档

此时查询数组字段是否包含至少一个具有指定值的元素

db.inventory.find( { tags: "red" } )
db.inventory.find( { dim_cm: { $gt: 25 } } )

查询包含指定元素集合的数组匹配的文档

使用 $all 运算符,此时无需考虑元素顺序

db.inventory.find( { tags: { $all: ["red", "blank"] } } )

✔️ 使用复合条件查询

下面的示例查询一个元素可以满足大于 15 的条件,而另一个元素可以满足小于 20 的条件,或者单个元素可以满足以下两个条件

db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } )

另外,使用 $elemMatch 运算符可在数组的元素上指定多个条件,以使至少一个数组元素满足所有指定的条件

以下示例查询在 dim_cm 数组中包含至少一个同时大于 22 和小于 30 的元素的文档

db.inventory.find( { dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } } )

通过数组索引位置查询

使用点表示法

db.inventory.find( { "dim_cm.1": { $gt: 25 } } )

使用点符号查询时,字段和嵌套字段必须在引号内

通过数组长度查询数组

使用 $size 运算符可按元素数量查询数组

db.inventory.find( { "tags": { $size: 3 } } )

查询嵌入文档

有例

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" }
]);

精准查询

请使用查询筛选文档 {<field>:<value>}

例如,以下查询选择字段大小等于文档 {h:14,w:21,uom:"cm"} 的所有文档(顺序也要一样哦)

db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } } )

MongoDB 不建议对嵌入式文档进行比较,因为这些操作需要与指定的 <value> 文档完全匹配,包括字段顺序。

部分查询

要在嵌套文档中的字段上指定查询条件,请使用点符号(field.nestedField

以下示例会选择嵌套在 size 字段中的 uom 字段等于 "in" 的所有文档:

db.inventory.find( { "size.uom": "in" } )

使用点符号查询时,字段和嵌套字段必须在引号内

以下查询在 **size **字段中嵌入的字段 h 上使用小于运算符

db.inventory.find( { "size.h": { $lt: 15 } } )

以下查询选择嵌套字段 h 小于 15,嵌套字段 uom 等于 “in”,状态字段等于 “D” 的所有文档

db.inventory.find( { "size.h": { $lt: 15 }, "size.uom": "in", status: "D" } )

查询嵌入式文档数组

有例

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 } ] }
]);

查询指定数组所属文档

下面的示例选择包含指定元素的数组所属的文档

db.inventory.find( { "instock": { warehouse: "A", qty: 5 } } )

字段顺序也要匹配!

在数组字段上指定查询条件

如果不知道嵌套在数组中的文档的索引位置,使用点 . 和嵌套文档中的字段名称(称为点表示法)来连接数组字段的名称。

db.inventory.find( { 'instock.qty': { $lte: 20 } } )

使用点表示法查询时,字段和索引必须在引号内

使用数组索引

下面的例子选择了所有 instock 数组的第一个元素是一个包含值小于或等于 20 的字段 qty 的文档

db.inventory.find( { 'instock.0.qty': { $lte: 20 } } )

为数组指定多个条件

使用 $elemMatch 运算符可在一组嵌入式文档上指定多个条件,以使至少一个嵌入式文档满足所有指定条件。

下面的示例查询 instock 数组中至少有一个嵌入式文档的文档,包含数量等于 5 的字段和数量等于 A 的字段

db.inventory.find( { "instock": { $elemMatch: { qty: 5, warehouse: "A" } } } )

下面的示例查询 instock 数组中至少有一个嵌入式文档的文档,该嵌入式文档的 qty 字段大于 10 且小于或等于 20 的文档

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

元素组合满足标准

如果数组字段上的复合查询条件未使用 $elemMatch 运算符,则查询将选择其数组包含满足条件的元素的任意组合的那些文档

下面的示例查询在 instock 阵列中的任何文档的数量字段大于 10,并且阵列中任何文档的数量字段小于或等于 20 的文档

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

下面的示例查询在 instock 数组中至少有一个包含数量等于 5 的嵌入式文档和至少一有个包含等于 A 的字段仓库的嵌入式文档的文档

db.inventory.find( { "instock.qty": 5, "instock.warehouse": "A" } )

查询空字段或缺少字段

有例

db.inventory.insertMany([
{ _id: 1, item: null },
{ _id: 2 }
])

相等过滤器

{item:null} 查询匹配包含值是 nullitem 字段或不包含 item 字段的文档

db.inventory.find( { item: null } )

非相等过滤器

要查询存在且不为 null 的字段,请使用 { $ne : null } 筛选器

const cursor = db.collection('inventory')
.find({ item: { $ne : null }
});

类型检查

{item:{$type:10}} 查询只匹配包含 item 字段值为 null 的文档;

db.inventory.find( { item : { $type: 10 } } )

存在性检查

{item:{$ exists:false}} 查询不包含 item 字段的文档匹配

db.inventory.find( { item : { $exists: false } } )