MongoDB 4.2 官方文档查询文档语句示例

本文介绍 MongoDB 中文档查询示例,详细内容参考 Query Documents

1. 基本查询示例

使用下面语句创建 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( {} )

上面语句类似于 SQL 中的:

SELECT * FROM inventory
1.2 相等匹配

相等匹配查询 ,语法:

<field>:<value> 

示例:

db.inventory.find( { status: "D" } )

上面语句类似于 SQL 中的:

SELECT * FROM inventory WHERE status = "D"
1.3 使用查询操作符

语法:

{ <field1>: { <operator1>: <value1> }, ... }

示例,在 inventory 集合中查询 status 是 “A” 或者 “D” 的:

db.inventory.find( { status: { $in: [ "A", "D" ] } } )

上面语句类似于 SQL 中的:

SELECT * FROM inventory WHERE status in ("A", "D")
1.4 AND 查询条件

示例,在 inventory 集合中查询status 等于 “A” 并且 qty 小于 30:

db.inventory.find( { status: "A", qty: { $lt: 30 } } )

上面语句类似于 SQL 中的:

SELECT * FROM inventory WHERE status = "A" AND qty < 30
1.4 OR 查询条件

使用 $or 操作符,满足 $or 后数组中的任意一个条件。示例:

db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )

上面语句类似于 SQL 中的:

SELECT * FROM inventory WHERE status = "A" OR qty < 30
1.5 AND 和 OR 操作符同时使用

示例,模糊匹配使用 $regex

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%")

2. 查询内嵌文档示例

使用下面语句创建 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" }
]);
2.1 内嵌文档相等匹配

要查询内嵌文档相等匹配,仍旧使用{ <field>: <value> }<value>
是要查询的文档。
示例,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.2 内嵌文档字段查询

To specify a query condition on fields in an embedded/nested document要针对内嵌文档中的字段进行查询,使用 . 符号连接,("field.nestedField")
示例,查询 size 中的 uom 等于 “in”:

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

内嵌文档使用查询操作符同样使用如下语法:

{ <field1>: { <operator1>: <value1> }, ... }

示例,查询 size 中的 h 小于15:

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

使用 AND 操作符
示例,查询 size,h 小于15,并且 size.uom 等于 in,并且 status 等于 D:

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

3. 数组查询

使用下面语句创建 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 ] }
]);
3.1 数组精确匹配

数组相等匹配同样使用 { <field>: <value> }<value>
是要查询的整个数组,数组中元素的顺序也需要保持一致。
示例,查询 tags 数组等于 [“red”, “blank”] (元素有先后顺序):

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

如果不考虑顺序和数组中其他元素,只要 tags 中包含 “red” 和 “blank” 就匹配,使用 $all 操作符:

db.inventory.find( { tags: { $all: ["red", "blank"] } } )
3.2 匹配一个数组元素

如果数组中至少 一个 元素包含特定的值,就可以匹配这些声明。
示例, tags 数组中有一个元素为 “red”:

db.inventory.find( { tags: "red" } )

示例,dim_cm 数组中有一个元素大于 25:

db.inventory.find( { dim_cm: { $gt: 25 } } )
3.3. 元素组合满足查询条件:

示例,dim_cm 数组中,只要有元素满足 “>15”,"<20" 这两个条件中的一个或多个,即匹配:

db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } )
3.4单个元素满足查询条件 $elemMatch

数组中有元素同时满足所有条件即匹配
示例,查询 dim_cm 有元素满足:">22" 和 “<30” 的文档:

db.inventory.find( { dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } } )
3.5 匹配数组中指定位置元素

使用 . 匹配数组中指定位置元素。
示例,匹配 dim_cm 数组中第二个元素大于25:

db.inventory.find( { "dim_cm.1": { $gt: 25 } } )
3.6 匹配数组长度

使用 $size 来匹配指定数组长度的文档
示例,匹配 tags 数组长度为3的所有文档:

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

4. 嵌入文档数组匹配

使用下面语句创建 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 内嵌文档类型数组精确匹配

数组中元素为内嵌文档,必须完全一样才能匹配,顺序也需要保持一致。
示例:

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

示例2:由于 instock 中位置不一致,无法查询初结果:

db.inventory.find( { "instock": { qty: 5, warehouse: "A" } } )
4.2 不指定数组索引匹配字段

如果你不知道文档在数组中的索引位置,用点号 (.) 将包含数组的字段的名字和内嵌文档的字段的名字连起来。
示例:匹配 instock 数组中至少有一个元素的 qty 字段 <= 20

db.inventory.find( { 'instock.qty': { $lte: 20 } } )
4.3 使用数组索引匹配嵌入文档中的字段

示例,匹配 instock 数组的第一个内嵌文档的 qty 字段小于等于20

db.inventory.find( { 'instock.0.qty': { $lte: 20 } } )
4.4 指定数组文档的多个查询条件
4.4.1 单个元素满足查询条件 $elemMatch

示例,匹配 instock 数组中至少有一个内嵌文档同时满足:qty: 5, warehouse: “A”:

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

示例,匹配 instock 数组中至少有一个内嵌文档同时满足: qty 大于10且小于等于20

db.inventory.find( { "instock": { $elemMatch: { qty: { $gt: 10, $lte: 20 } } } } )
4.4.2 元素组合满足查询条件

示例1,匹配 instock 数组中有任意文档满足 qty>10 和 qty<=20,满足这两个条件的不需要一定是同一个文档

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

满足查询结果:

// 1
{
    "_id": ObjectId("5ea16e133b775054146b1304"),
    "item": "journal",
    "instock": [
        {
            "warehouse": "A",
            "qty": 5
        },
        {
            "warehouse": "C",
            "qty": 15
        }
    ]
}

// 2
{
    "_id": ObjectId("5ea16e133b775054146b1306"),
    "item": "paper",
    "instock": [
        {
            "warehouse": "A",
            "qty": 60
        },
        {
            "warehouse": "B",
            "qty": 15
        }
    ]
}

// 3
{
    "_id": ObjectId("5ea16e133b775054146b1307"),
    "item": "planner",
    "instock": [
        {
            "warehouse": "A",
            "qty": 40
        },
        {
            "warehouse": "B",
            "qty": 5
        }
    ]
}

// 4
{
    "_id": ObjectId("5ea16e133b775054146b1308"),
    "item": "postcard",
    "instock": [
        {
            "warehouse": "B",
            "qty": 15
        },
        {
            "warehouse": "C",
            "qty": 35
        }
    ]
}

示例2,匹配 instock 数组中有任意文档满足 qty=5 和 warehouse=A,满足这两个条件的不需要一定是同一个文档

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

满足查询结果:

// 1
{
    "_id": ObjectId("5ea16e133b775054146b1304"),
    "item": "journal",
    "instock": [
        {
            "warehouse": "A",
            "qty": 5
        },
        {
            "warehouse": "C",
            "qty": 15
        }
    ]
}

// 2
{
    "_id": ObjectId("5ea16e133b775054146b1307"),
    "item": "planner",
    "instock": [
        {
            "warehouse": "A",
            "qty": 40
        },
        {
            "warehouse": "B",
            "qty": 5
        }
    ]
}

5. 查询返回字段

    默认情况下,MongoDB 会返回匹配到文档的所有字段,为了减少应用和 MongoDB 之间的流量传输,我们可以指定查询返回字段。
使用下面语句创建 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 只返回指定字段和 _id 字段

在 projection document 中设置<field> :1来指定需要返回的字段,_id 默认返回。
示例,返回 _id,item,status 三个字段:

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

在一个 projection 中不能同时指定包括和排除字段,除了排除 _id 字段。 在指定其他字段的同时可以排除 _id 字段。

5.2 排除字段,返回其他所有字段

在 projection document 中设置<field> :0来排除返回字段,除了排除的字段之外,其他所有字段会被返回
示例,返回除了 status 和 instock 之外的所有字段:

db.inventory.find( { status: "A" }, { status: 0, instock: 0 } )
5.3 不返回 _id 字段

在 projection document 中设置 _id:0可以取消返回 _id 字段。
示例,返回 item,status 两个字段:

db.inventory.find( { status: "A" }, { item: 1, status: 1, _id: 0 } )
5.4 内嵌文档返回指定字段

使用 . 选择内嵌文档字段,在 projection document 中设置为1。
示例,返回 _id,item,status,size.uom:

db.inventory.find(
   { status: "A" },
   { item: 1, status: 1, "size.uom": 1 }
)
5.5 内嵌文档排除字段

示例,除了 size.uom 之外返回其他所有字段

db.inventory.find(
   { status: "A" },
   { "size.uom": 0 }
)
5.6 内嵌文档数组

示例,返回 _id,item,status 和 instock 数组中每个元素的 qty 字段

db.inventory.find( { status: "A" }, { item: 1, status: 1, "instock.qty": 1 } )
5.7 返回数组中特定的数组元素

对于包含数组的字段,MongoDB提供了下面的映射操作符: $elemMatch, $slice, 以及 $。 $elemMatch , $slice ,以及 $ 是用来指定返回数组中包含映射元素的 唯一 方式。
示例,返回 instock 数组中的最后一个元素

db.inventory.find( { status: "A" }, { item: 1, status: 1, instock: { $slice: -1 } } )

返回结果:

// 1
{
    "_id": ObjectId("5ea255e63b775054146b130e"),
    "item": "journal",
    "status": "A",
    "instock": [
        {
            "warehouse": "A",
            "qty": 5
        }
    ]
}

// 2
{
    "_id": ObjectId("5ea255e63b775054146b130f"),
    "item": "notebook",
    "status": "A",
    "instock": [
        {
            "warehouse": "C",
            "qty": 5
        }
    ]
}

// 3
{
    "_id": ObjectId("5ea255e63b775054146b1312"),
    "item": "postcard",
    "status": "A",
    "instock": [
        {
            "warehouse": "B",
            "qty": 15
        },
        {
            "warehouse": "C",
            "qty": 35
        }
    ]
}

6. 查询值为 null 或不存在的字段

使用下面语句创建 inventory 集合并往里面插入数据:

db.inventory.insertMany([
   { _id: 1, item: null },
   { _id: 2 }
])
6.1 相等过滤

使用{ item : null }匹配。示例,查询 item 为 null 的或者 item 字段不存在的文档:

db.inventory.find( { item: null } )
6.2 使用类型 $type 匹配

BSON Types 中 Number 等于 10 代表 null。{ $type: 10 }只会匹配到值为 null 的,不会匹配到字段不存在的情况,示例,查询 item 为 null 的文档:

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

返回结果:

// 1
{
    "_id": 1,
    "item": null
}
6.3 使用 $exists 匹配

$exists 只会匹配到字段不存在的文档
示例,查询不包含 item 字段的文档:

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

7. MongoDB shell 中使用游标 Cursor

    db.collection.find() 会返回一个游标,迭代这个游标即可获得结果文档。在 mongo shell 中,如果没有把返回的游标赋值给一个 var 变量,那么游标会自动获取前20个文档打印在控制台上。下面的示例展示如何利用 iterator index 手动迭代游标,获取返回文档。

7.1 手动迭代游标

示例1,获取游标,迭代20次

var myCursor = db.users.find( { type: 2 } );
myCursor

示例2,迭代游标,使用游标的 next() 方法获取每个文档

var myCursor = db.users.find( { type: 2 } );
while (myCursor.hasNext()) {
   printjson(myCursor.next());
}

示例3,使用 printjson() 代替 print(tojson())

var myCursor = db.users.find( { type: 2 } );
while (myCursor.hasNext()) {
   printjson(myCursor.next());
}

示例4,使用游标的 forEach() 方法迭代

var myCursor =  db.users.find( { type: 2 } );
myCursor.forEach(printjson);
7.2 index 迭代

在 mongo shell 中,可以使用 toArray() 方法去遍历游标,方法返回文档数组,根据数组下标可以获得具体文档,示例:

var myCursor = db.inventory.find( { type: 2 } );
var documentArray = myCursor.toArray();
var myDocument = documentArray[3];

使用 toArray() 方法会所有匹配到的文档数据加载到内存中,toArray() 会直接遍历完整个游标,另外一些驱动 sdk 会提供方法,直接在游标中使用下标(cursor[index])的方法来获取文档,对比使用 toArray() (先通过 toArray() 获取数组,然后再在数组中使用下标获取指定文档)更为方便。示例:

var myCursor = db.users.find( { type: 2 } );
var myDocument = myCursor[1];

上面指令等价于:

var myDocument = myCursor.toArray() [1];
发布了6 篇原创文章 · 获赞 0 · 访问量 87

猜你喜欢

转载自blog.csdn.net/baidu_33722511/article/details/105701926