MongoDB查询时指定返回的字段,类似mysql 中的select 中的指定字段,可选返回指定字段或排除某些字段后返回剩余字段。

测试数据

1
2
3
4
5
6
7
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: 5 }, { 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: 25 }, { warehouse: "C", qty: 35 } , { warehouse: "C", qty: 45 }] }
]);

返回所有字段

1
2
3
4
5
6
7
8
9
10
// select * from inventory 
db.collection.find({})

// 没有过滤条件可省略{}
// select * from inventory
db.collection.find()

// 带条件
// SELECT * from inventory WHERE status = "A"
db.collection.find({status:“A”})

返回指定字段

默认_id字段是会返回的,其他字段可通过将设置为1。

1
2
3
// SELECT _id, item, status from inventory WHERE status = "A"
db.inventory.find( { status: "A" }, { item: 1, status: 1 } )

如果需要排除_id

1
2
// SELECT  item, status from inventory WHERE status = "A"
db.inventory.find( { status: "A" }, { item: 1, status: 1, _id:0} )

返回排除字段之外的其他字段

像排除_id字段之外一样,将设置为0可排除指定字段,此时会返回剩余的所有字段。

_id字段之外,其他字段,要么全为1,要么全为0,_id字段不设置默认是1.

1
2
// 返回除status和instock的其他字段
db.inventory.find( { status: "A" }, { status: 0, instock: 0 } )

如果非_id字段包括了0 和1,会报错

1
2
3
db.inventory.find({status:"A"}, {item:0, size:1})

> [Error] Projection cannot have a mix of inclusion and exclusion.

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

例如size字段中只想返回uom字段

1
2
3
4
5
6
7
8
9
10
db.inventory.find(
{ status: "A" },
{ item: 1, status: 1, "size.uom": 1 }
)

//从MongoDB 4.4开始,你也可以使用嵌套的形式指定嵌入的字段
db.inventory.find(
{ status: "A" },
{ item: 1, status: 1, size: {uom:1} }
)

排除嵌入式文档中的特定字段也是设置为0. 同样,所有字段除_id外必须同时为1或同时为0.

数组也可以用类似方式过滤。

1
db.inventory.find( {}, { item: 0, status: 0, "instock.qty":0} )

结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// 1
{
"_id": ObjectId("5ff6b6ac4f64000086000c04"),
"size": {
"h": 14,
"w": 21,
"uom": "cm"
},
"instock": [
{
"warehouse": "A"
}
]
}

// 2
{
"_id": ObjectId("5ff6b6ac4f64000086000c05"),
"size": {
"h": 8.5,
"w": 11,
"uom": "in"
},
"instock": [
{
"warehouse": "C"
}
]
}

// 3
{
"_id": ObjectId("5ff6b6ac4f64000086000c06"),
"size": {
"h": 8.5,
"w": 11,
"uom": "in"
},
"instock": [
{
"warehouse": "A"
}
]
}

// 4
{
"_id": ObjectId("5ff6b6ac4f64000086000c07"),
"size": {
"h": 22.85,
"w": 30,
"uom": "cm"
},
"instock": [
{
"warehouse": "A"
}
]
}

// 5
{
"_id": ObjectId("5ff6b6ac4f64000086000c08"),
"size": {
"h": 10,
"w": 15.25,
"uom": "cm"
},
"instock": [
{
"warehouse": "B"
},
{
"warehouse": "C"
},
{
"warehouse": "C"
},
{
"warehouse": "C"
}
]
}

返回数组中的项目特定数组元素

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

$slice

返回数组指定个数的元素,只有一个数代表返回数据的数量,[x,y]形式,x是下标,y是返回数据的 数量。

比如数组[1,2,3,4]

正向 $slice: 1 ,从左往右找1个, 结果是1, $slice: 2, 结果是 1,2

从指定下标找 $slice: [1,3], 是从下标1 往右找3个,结果是 2,3,4,第一个数的下标是0.

逆向, $slice: -1 ,从最右往左找一个,结果是4, $slice: -2,结果是 3,4

从指定下标找,$slice: [-2,1], 最后一个数的下标是-1, 从下标为-2往左找一个,结果为 3

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

$elemMatch

查询

1
db.inventory.find( {}, { item: 1, status: 1, instock: { $elemMatch: {qty:{$gt:5}}} } )

结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// 1
{
"_id": ObjectId("5ff6b6ac4f64000086000c04"),
"item": "journal",
"status": "A"
}

// 2
{
"_id": ObjectId("5ff6b6ac4f64000086000c05"),
"item": "notebook",
"status": "A"
}

// 3
{
"_id": ObjectId("5ff6b6ac4f64000086000c06"),
"item": "paper",
"status": "D",
"instock": [
{
"warehouse": "A",
"qty": 60
}
]
}

// 4
{
"_id": ObjectId("5ff6b6ac4f64000086000c07"),
"item": "planner",
"status": "D",
"instock": [
{
"warehouse": "A",
"qty": 40
}
]
}

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

可以看到结果5条数据全部返回了,这里要注意两点,

  1. 这里instock: { $elemMatch: {qty:{$gt:5}}}并不是where后面的条件,所以并不是只返回 qty>5 的数据,而是根据前面的 { } 返回所有记录
  2. instock: { $elemMatch: {qty:{$gt:5}}}限制的是数组中返回的结果,并且只返回符合条件的第一条。前两条数据qty = 5 不符合条件,没有返回instock数组内容,后面3条均instock数组都只返回了一条数据。

$elemMatch: {qty:{$gt:5} 之后的查询条件

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

语法

1
2
3
4
db.collection.find( { <array>: <condition> ... },
{ "<array>.$": 1 } )
db.collection.find( { <array.field>: <condition> ...},
{ "<array>.$": 1 } )

从MongoDB 4.4开始,$投影运算符只能出现在字段路径的末尾。例如“ field.$”或“ fieldA.fieldB.$”, fieldA.$.fieldB 不能使用了。

数据

1
2
3
4
5
6
db.students.insert([{ "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 90 ] },
{ "_id" : 2, "semester" : 1, "grades" : [ 90, 88, 92 ] },
{ "_id" : 3, "semester" : 1, "grades" : [ 85, 100, 90 ] },
{ "_id" : 4, "semester" : 2, "grades" : [ 79, 85, 80 ] },
{ "_id" : 5, "semester" : 2, "grades" : [ 88, 88, 92 ] },
{ "_id" : 6, "semester" : 2, "grades" : [ 95, 90, 96 ] }])

查询

1
2
db.students.find( { semester: 1, grades: { $gte: 85 } },
{ "grades.$": 1 } )

结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 1
{
"_id": 1,
"grades": [
87
]
}

// 2
{
"_id": 2,
"grades": [
90
]
}

// 3
{
"_id": 3,
"grades": [
85
]
}

参考文章链接:

MongoDB中文手册: 从查询返回的项目字段