示例集合

 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
docs := []interface{}{
	bson.D{
		{"item", "journal"},
		{"qty", 25},
		{"size", bson.D{
			{"h", 14},
			{"w", 21},
			{"uom", "cm"},
		}},
		{"status", "A"},
	},
	bson.D{
		{"item", "notebook"},
		{"qty", 50},
		{"size", bson.D{
			{"h", 8.5},
			{"w", 11},
			{"uom", "in"},
		}},
		{"status", "A"},
	},
	bson.D{
		{"item", "paper"},
		{"qty", 100},
		{"size", bson.D{
			{"h", 8.5},
			{"w", 11},
			{"uom", "in"},
		}},
		{"status", "D"},
	},
	bson.D{
		{"item", "planner"},
		{"qty", 75},
		{"size", bson.D{
			{"h", 22.85},
			{"w", 30},
			{"uom", "cm"},
		}},
		{"status", "D"},
	},
	bson.D{
		{"item", "postcard"},
		{"qty", 45},
		{"size", bson.D{
			{"h", 10},
			{"w", 15.25},
			{"uom", "cm"},
		}},
		{"status", "A"},
	},
}

result, err := coll.InsertMany(context.Background(), docs)
 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
docs := []interface{}{
	bson.D{
		{"item", "journal"},
		{"qty", 25},
		{"tags", bson.A{"blank", "red"}},
		{"dim_cm", bson.A{14, 21}},
	},
	bson.D{
		{"item", "notebook"},
		{"qty", 50},
		{"tags", bson.A{"red", "blank"}},
		{"dim_cm", bson.A{14, 21}},
	},
	bson.D{
		{"item", "paper"},
		{"qty", 100},
		{"tags", bson.A{"red", "blank", "plain"}},
		{"dim_cm", bson.A{14, 21}},
	},
	bson.D{
		{"item", "planner"},
		{"qty", 75},
		{"tags", bson.A{"blank", "red"}},
		{"dim_cm", bson.A{22.85, 30}},
	},
	bson.D{
		{"item", "postcard"},
		{"qty", 45},
		{"tags", bson.A{"blue"}},
		{"dim_cm", bson.A{10, 15.25}},
	},
}

result, err := coll.InsertMany(context.Background(), docs)
 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
docs := []interface{}{
	bson.D{
		{"item", "journal"},
		{"instock", bson.A{
			bson.D{
				{"warehouse", "A"},
				{"qty", 5},
			},
			bson.D{
				{"warehouse", "C"},
				{"qty", 15},
			},
		}},
	},
	bson.D{
		{"item", "notebook"},
		{"instock", bson.A{
			bson.D{
				{"warehouse", "C"},
				{"qty", 5},
			},
		}},
	},
	bson.D{
		{"item", "paper"},
		{"instock", bson.A{
			bson.D{
				{"warehouse", "A"},
				{"qty", 60},
			},
			bson.D{
				{"warehouse", "B"},
				{"qty", 15},
			},
		}},
	},
	bson.D{
		{"item", "planner"},
		{"instock", bson.A{
			bson.D{
				{"warehouse", "A"},
				{"qty", 40},
			},
			bson.D{
				{"warehouse", "B"},
				{"qty", 5},
			},
		}},
	},
	bson.D{
		{"item", "postcard"},
		{"instock", bson.A{
			bson.D{
				{"warehouse", "B"},
				{"qty", 15},
			},
			bson.D{
				{"warehouse", "C"},
				{"qty", 35},
			},
		}},
	},
}

result, err := coll.InsertMany(context.Background(), docs)
 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
docs := []interface{}{
	bson.D{
		{"item", "journal"},
		{"status", "A"},
		{"size", bson.D{
			{"h", 14},
			{"w", 21},
			{"uom", "cm"},
		}},
		{"instock", bson.A{
			bson.D{
				{"warehouse", "A"},
				{"qty", 5},
			},
		}},
	},
	bson.D{
		{"item", "notebook"},
		{"status", "A"},
		{"size", bson.D{
			{"h", 8.5},
			{"w", 11},
			{"uom", "in"},
		}},
		{"instock", bson.A{
			bson.D{
				{"warehouse", "EC"},
				{"qty", 5},
			},
		}},
	},
	bson.D{
		{"item", "paper"},
		{"status", "D"},
		{"size", bson.D{
			{"h", 8.5},
			{"w", 11},
			{"uom", "in"},
		}},
		{"instock", bson.A{
			bson.D{
				{"warehouse", "A"},
				{"qty", 60},
			},
		}},
	},
	bson.D{
		{"item", "planner"},
		{"status", "D"},
		{"size", bson.D{
			{"h", 22.85},
			{"w", 30},
			{"uom", "cm"},
		}},
		{"instock", bson.A{
			bson.D{
				{"warehouse", "A"},
				{"qty", 40},
			},
		}},
	},
	bson.D{
		{"item", "postcard"},
		{"status", "A"},
		{"size", bson.D{
			{"h", 10},
			{"w", 15.25},
			{"uom", "cm"},
		}},
		{"instock", bson.A{
			bson.D{
				{"warehouse", "B"},
				{"qty", 15},
			},
			bson.D{
				{"warehouse", "EC"},
				{"qty", 35},
			},
		}},
	},
}

result, err := coll.InsertMany(context.Background(), docs)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
docs := []interface{}{
	bson.D{
		{"_id", 1},
		{"item", nil},
	},
	bson.D{
		{"_id", 2},
	},
}

result, err := coll.InsertMany(context.Background(), docs)

选择集合中的所有文档

要选择集合中的所有文档,请将空文档作为查询过滤器参数传递给find方法。查询过滤器参数确定选择条件:

1
2
3
4
cursor, err := coll.Find(
	context.Background(),
	bson.D{},
)

此操作对应于以下SQL语句:

1
SELECT * FROM inventory

指定相等条件

以下示例从inventory集合中选择status等于"D"的所有文档:

1
2
3
4
cursor, err := coll.Find(
	context.Background(),
	bson.D{{"status", "D"}},
)

此操作对应于以下SQL语句:

1
SELECT * FROM inventory WHERE status = "D"

查询运算符

以下示例从inventory 集合中检索status等于"A"或"D"的所有文档:

1
2
3
cursor, err := coll.Find(
	context.Background(),
	bson.D{{"status", bson.D{{"$in", bson.A{"A", "D"}}}}})

注意

尽管可以使用$or运算符表示此查询,但是在同一字段上执行相等性检查时,请使用$in运算符而不是$or运算符。

该操作对应于以下SQL语句:

1
SELECT * FROM inventory WHERE status in ("A", "D")

有关MongoDB查询运算符的完整列表,请参阅查询和投影运算符文档

指定AND条件

复合查询可以为集合文档中的多个字段指定条件。AND将复合查询的子句连接起来,以便查询选择集合中符合所有条件的文档。

以下示例检索inventory集合中status等于"A" 且qty小于($lt)30的所有文档:

1
2
3
4
5
6
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"status", "A"},
		{"qty", bson.D{{"$lt", 30}}},
	})

该操作对应于以下SQL语句:

1
SELECT * FROM inventory WHERE status = "A" AND qty < 30

有关其他MongoDB比较运算符,请参阅比较运算符

指定OR条件

使用$or运算符,您可以指定一个复合查询,该查询将每个子句与一个逻辑连接符连接在一起,OR以便该查询选择集合中至少匹配一个条件的文档。

以下示例检索集合中status等于"A"或qty小于($lt)30的所有文档:

1
2
3
4
5
6
7
8
9
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"$or",
			bson.A{
				bson.D{{"status", "A"}},
				bson.D{{"qty", bson.D{{"$lt", 30}}}},
			}},
	})

该操作对应于以下SQL语句:

1
SELECT * FROM inventory WHERE status = "A" OR qty < 30

注意

使用比较运算符的查询 需进行类型包围

指定AND和OR条件

在下面的例子中,复合查询中选择该集合中的所有文档,其中status等于"A"和任一qty小于($lt)30或item开始于字符p:

1
2
3
4
5
6
7
8
9
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"status", "A"},
		{"$or", bson.A{
			bson.D{{"qty", bson.D{{"$lt", 30}}}},
			bson.D{{"item", primitive.Regex{Pattern: "^p", Options: ""}}},
		}},
	})

该操作对应于以下SQL语句:

1
SELECT * FROM inventory WHERE status = "A" AND ( qty < 30 OR item LIKE "p%")

注意

MongoDB支持正则表达式$regex查询以执行字符串模式匹配。

特性

游标

该Collection.Find 函数返回一个指针到匹配的文件。有关 更多信息,请参见Cursor文档

读取隔离

3.2版中的新功能。

对于对副本集和副本集分片的读取,读取关注使客户端可以为其读取选择隔离级别。有关更多信息,请参见读关注的内容。

查询嵌入/嵌套文档

匹配嵌入/嵌套文档

例如,以下查询选择字段size等于文档的所有 文档:{ h: 14, w: 21, uom: "cm" }

1
2
3
4
5
6
7
8
9
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"size", bson.D{
			{"h", 14},
			{"w", 21},
			{"uom", "cm"},
		}},
	})

整个嵌入式文档上的相等匹配要求与指定文档(包括字段顺序)完全匹配<value>。例如,以下查询与inventory集合中的任何文档都不匹配 :

1
2
3
4
5
6
7
8
9
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"size", bson.D{
			{"w", 21},
			{"h", 14},
			{"uom", "cm"},
		}},
	})

在嵌套字段上查询

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

注意

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

在嵌套字段上指定相等匹配

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

1
2
3
4
cursor, err := coll.Find(
	context.Background(),
	bson.D{{"size.uom", "in"}},
)

使用查询运算符指定匹配项

以下查询$lt在字段中h嵌入的size字段上使用小于运算符():

1
2
3
4
5
6
7
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"size.h", bson.D{
			{"$lt", 15},
		}},
	})

指定AND条件

以下查询选择嵌套字段h小于15,嵌套字段uom等于"in"和status字段等于"D"的所有文档:

1
2
3
4
5
6
7
8
9
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"size.h", bson.D{
			{"$lt", 15},
		}},
		{"size.uom", "in"},
		{"status", "D"},
	})

查询数组

匹配一个数组

下面的示例查询所有文档,其中字段标签值是按指定顺序恰好具有两个元素(“red”和“ blank”)的数组:

1
2
3
4
cursor, err := coll.Find(
	context.Background(),
	bson.D{{"tags", bson.A{"red", "blank"}}},
)

相反,如果您希望找到一个同时包含元素"red"和的数组 “blank”,而不考虑该数组中的顺序或其他元素,请使用$all运算符:

1
2
3
4
5
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"tags", bson.D{{"$all", bson.A{"red", "blank"}}}},
	})

在数组中查询元素

以下示例查询所有文档,其中tags是一个包含字符串"red"作为其元素之一的数组:

1
2
3
4
5
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"tags", "red"},
	})

例如,以下操作查询数组dim_cm包含至少一个值大于25的元素的所有文档。

1
2
3
4
5
6
7
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"dim_cm", bson.D{
			{"$gt", 25},
		}},
	})

指定数组元素多重条件

在数组元素上指定复合条件时,可以指定查询,以使单个数组元素满足这些条件,或者数组元素的任何组合均满足条件。

使用数组元素上的复合过滤条件查询数组

下面的示例查询文档,其中dim_cm数组包含某种组合满足查询条件的元素;例如,一个元素可以满足大于15 条件,而另一个元素可以满足小于20条件,或者一个元素可以满足以下两个条件:

1
2
3
4
5
6
7
8
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"dim_cm", bson.D{
			{"$gt", 15},
			{"$lt", 20},
		}},
	})

查询满足多个条件的数组元素

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

以下示例查询文档,其中dim_cm数组包含至少一个同时大于($gt)22和小于($lt)30的元素:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"dim_cm", bson.D{
			{"$elemMatch", bson.D{
				{"$gt", 22},
				{"$lt", 30},
			}},
		}},
	})

查询数组某个索引位置的元素

使用点表示法,您可以为数组的特定索引或位置处的元素指定查询条件。该数组使用基于零的索引。

注意

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

以下示例查询数组中第二个元素dim_cm大于的所有文档25:

1
2
3
4
5
6
7
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"dim_cm.1", bson.D{
			{"$gt", 25},
		}},
	})

通过长度数组查询数组

使用$size运算符可按元素数量查询数组。例如,以下选择数组tags具有3个元素的文档 。

1
2
3
4
5
6
7
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"tags", bson.D{
			{"$size", 3},
		}},
	})

查询嵌入式文档数组

查询嵌套在数组中的文档

下面的示例选择instock数组中的元素 与指定文档匹配的所有文档:

1
2
3
4
5
6
7
8
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"instock", bson.D{
			{"warehouse", "A"},
			{"qty", 5},
		}},
	})

整个嵌入式/嵌套文档上的相等匹配要求 与指定文档(包括字段顺序)完全匹配。例如,以下查询与inventory集合中的任何文档都不匹配 :

1
2
3
4
5
6
7
8
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"instock", bson.D{
			{"qty", 5},
			{"warehouse", "A"},
		}},
	})

在文档数组中的字段上指定查询条件

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

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

下面的示例选择instock数组包含至少一个嵌入式文档的所有文档,其中嵌入式文档包含qty值小于或等于20的字段:

1
2
3
4
5
6
7
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"instock.qty", bson.D{
			{"$lte", 20},
		}},
	})

使用数组索引来查询一个字段中嵌入文档

使用点表示法,可以为文档中特定索引或数组位置的字段指定查询条件。该数组使用基于零的索引。

注意

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

下面的示例选择instock数组包含qty,其值小于或等于20的字段作为其文档的第一个元素的所有文档:

1
2
3
4
5
6
7
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"instock.0.qty", bson.D{
			{"$lte", 20},
		}},
	})

指定文件的数组建立多个条件

在嵌套在文档数组中的多个字段上指定条件时,可以指定查询,以使单个文档满足这些条件,或者数组中文档的任何组合(包括单个文档)都满足条件。

单个嵌套文档在嵌套字段上满足多个查询条件

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

下面的示例查询文档,其中instock数组具有至少一个嵌入式文档,该文档同时包含qty等于5的字段和warehouse等于A的字段:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"instock", bson.D{
			{"$elemMatch", bson.D{
				{"qty", 5},
				{"warehouse", "A"},
			}},
		}},
	})

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"instock", bson.D{
			{"$elemMatch", bson.D{
				{"qty", bson.D{
					{"$gt", 10},
					{"$lte", 20},
				}},
			}},
		}},
	})

元素组合满足标准

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

例如,以下查询匹配文档,其中嵌套在instock数组中的任何文档的qty字段大于10,而数组中的任何文档(但不一定是相同的嵌入式文档)的qty字段小于或等于20:

1
2
3
4
5
6
7
8
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"instock.qty", bson.D{
			{"$gt", 10},
			{"$lte", 20},
		}},
	})

下列示例查询instock数组具有至少一个嵌入的文档包含该字段qty等于5和至少一个嵌入的文档(但不一定是相同的嵌入的文档)包含该字段warehouse等于A:

1
2
3
4
5
6
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"instock.qty", 5},
		{"instock.warehouse", "A"},
	})

投影查询返回的字段

默认情况下,MongoDB中的查询返回匹配文档中的所有字段。要限制MongoDB发送给应用程序的数据量,可以包含一个投影文档以指定或限制要返回的字段。

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

下面的示例返回inventory集合中status等于的所有文档的所有字段 “A”:

1
2
3
4
cursor, err := coll.Find(
	context.Background(),
	bson.D{{"status", "A"}},
)

该操作对应于以下SQL语句:

1
SELECT * from inventory WHERE status = "A"

返回指定字段和仅_id字段

通过在投影文档中将设置为<field>,投影可以明确包含多个字段。以下操作返回与查询匹配的所有文档。在结果集中,只有item,status以及默认情况下,_id字段会在匹配的文档中返回。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
projection := bson.D{
	{"item", 1},
	{"status", 1},
}

cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"status", "A"},
	},
	options.Find().SetProjection(projection),
)

该操作对应于以下SQL语句:

1
SELECT _id, item, status from inventory WHERE status = "A"

禁止_id返回

您可以_id通过将其设置0为投影中的结果来从结果中删除该字段 ,如以下示例所示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
projection := bson.D{
	{"item", 1},
	{"status", 1},
	{"_id", 0},
}

cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"status", "A"},
	},
	options.Find().SetProjection(projection),
)

该操作对应于以下SQL语句:

1
SELECT item, status from inventory WHERE status = "A"

注意

除该_id字段外,您无法在投影文档中合并包含和排除语句。

返回所有但排除某些字段

无需列出要在匹配文档中返回的字段,而是可以使用投影排除特定字段。以下示例返回匹配文档中的status和字段以外的所有字段instock:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
projection := bson.D{
	{"status", 0},
	{"instock", 0},
}

cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"status", "A"},
	},
	options.Find().SetProjection(projection),
)

注意

除该_id字段外,您无法在投影文档中合并包含和排除语句。

返回内嵌文档的特定字段

您可以返回嵌入式文档中的特定字段。使用点表示法引用嵌入字段并在投影文档中将其设置为1。

以下示例返回:

  • _id(默认情况下返回)
  • item,
  • status,
  • size中的uom字段。

该uom字段将保留在size文档中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
projection := bson.D{
	{"item", 1},
	{"status", 1},
	{"size.uom", 1},
}

cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"status", "A"},
	},
	options.Find().SetProjection(projection),
)

禁止内嵌文档特定的字段

您可以隐藏嵌入式文档中的特定字段。使用点表示法引用投影文档中的嵌入字段并将其设置为0。

下面的示例指定一个排除文档uom 内部字段的投影size。所有其他字段均在匹配的文档中返回:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
projection := bson.D{
	{"size.uom", 0},
}

cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"status", "A"},
	},
	options.Find().SetProjection(projection),
)

在数组中的嵌入式文档上投影

使用点符号可将嵌入数组的文档中的特定字段投影。

以下示例指定要返回的投影:

  • _id(默认情况下返回)
  • item,
  • status,
  • qty文档中的字段嵌入在instock数组中。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
projection := bson.D{
	{"item", 1},
	{"status", 1},
	{"instock.qty", 1},
}

cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"status", "A"},
	},
	options.Find().SetProjection(projection),
)

投影返回数组中的特定数组元素

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

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
projection := bson.D{
	{"item", 1},
	{"status", 1},
	{"instock", bson.D{
		{"$slice", -1},
	}},
}

cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"status", "A"},
	},
	options.Find().SetProjection(projection),
)

$elemMatch$slice,和$是投影特定元素以包含在返回数组中的唯一方法。例如,您不能使用数组索引来投影特定的数组元素。例如include("instock.0")不会将数组与第一个元素一起投影。

查询空字段或缺少字段

MongoDB中的不同查询运算符对待null值的方式有所不同。

重要

nil与MongoDB Go驱动程序一起使用以查询null或缺少MongoDB中的字段。

相等过滤器

item => nil查询匹配包含值等于nil或不包含该字段的文档。

1
2
3
4
5
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"item", nil},
	})

该查询返回集合中的两个文档。

类型检查

以下查询仅匹配 包含item其值为BSON类型 Null(类型编号10)的字段的 文档:

1
2
3
4
5
6
7
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"item", bson.D{
			{"$type", 10},
		}},
	})

该查询仅返回该item字段值为的文档null。

存在检查

以下示例查询不包含字段的文档。

1
2
3
4
5
6
7
cursor, err := coll.Find(
	context.Background(),
	bson.D{
		{"item", bson.D{
			{"$exists", false},
		}},
	})

该查询仅返回不包含该item字段的文档。

在mongoShell中迭代游标

db.collection.find()方法返回一个游标。要访问文档,您需要迭代游标。但是,在 mongoshell中,如果未使用var关键字将返回的光标分配给变量,则光标将自动迭代多达20次,以打印结果中的前20个文档。

以下示例描述了手动迭代游标以访问文档或使用迭代器索引的方法。

手动迭代游标

在mongoshell中,当您find()使用var关键字将方法返回的游标分配给变量时,游标不会自动进行迭代。

您可以在shell中调用cursor变量以进行多达20次迭代 [1]并打印匹配的文档,如以下示例所示:

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

myCursor

您还可以使用cursor方法next()访问文档,如以下示例所示:

1
2
3
4
5
var myCursor = db.users.find( { type: 2 } );

while (myCursor.hasNext()) {
   print(tojson(myCursor.next()));
}

作为替代的打印操作,请考虑使用printjson()方法来替换print(tojson()):

1
2
3
4
5
var myCursor = db.users.find( { type: 2 } );

while (myCursor.hasNext()) {
   printjson(myCursor.next());
}

您可以使用cursor方法forEach()来迭代光标并访问文档,如以下示例所示:

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

myCursor.forEach(printjson);

有关游标方法的更多信息,请参见JavaScript游标方法和驱动程序文档。

迭代指针

在mongo外壳程序中,可以使用 toArray()方法来迭代游标并以数组形式返回文档,如下所示:

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

toArray()方法将游标返回的所有文档加载到RAM中。该toArray() 方法耗尽游标。

此外,某些驱动程序通过使用光标(即cursor[index])上的索引来提供对文档的访问 。这是首先调用该toArray()方法然后在结果数组上使用索引的快捷方式。

考虑以下示例:

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

myCursor[1]等效于下面的例子:

1
myCursor.toArray() [1];

游标特性

关闭非活动游标

默认情况下,服务器将在闲置10分钟或客户端用尽光标后自动关闭光标。要在mongoshell程序中覆盖此特性,可以使用以下cursor.noCursorTimeout()方法:

1
var myCursor = db.users.find().noCursorTimeout();

设置该noCursorTimeout选项后,必须使用cursor.close()或通过用尽光标的结果来关闭光标。

光标隔离

当游标返回文档时,其他操作可能会与查询交错。

光标批次

MongoDB服务器批量返回查询结果。批处理中的数据量将不超过BSON文档的最大大小。要覆盖批次的默认大小,请参见batchSize()和 limit()。

在新版本3.4:find(), aggregate(), listIndexes,和 listCollections最大的每批16MB返回。batchSize()可以强制执行一个较小的限制,但不能执行较大的限制。

find()并且aggregate()操作的初始批处理大小默认为101个文档。getMore 针对结果游标发出的后续操作没有默认的批处理大小,因此它们仅受16MB消息大小的限制。

对于包含不带索引的排序操作的查询,服务器必须在返回任何结果之前将所有文档加载到内存中以执行排序。

当您遍历游标并到达返回批次的末尾时,如果还有更多结果,cursor.next()将执行来检索下一个批次。若要查看在迭代游标时批处理中剩余多少文档,可以使用方法,如以下示例所示:getMore operationobjsLeftInBatch()

1
2
3
4
5
var myCursor = db.inventory.find();

var myFirstDocument = myCursor.hasNext() ? myCursor.next() : null;

myCursor.objsLeftInBatch();

游标信息

db.serverStatus()方法返回包含metrics字段的文档。该 metrics字段包含metrics.cursor具有以下信息的 字段:

  • 自上次服务器重新启动以来超时的游标数
  • DBQuery.Option.noTimeout设置了选项以防止一段时间不活动后超时的打开游标的数量
  • “固定”打开游标的数量
  • 打开的游标总数

考虑以下示例,该示例调用 db.serverStatus()方法并metrics从结果中访问字段,然后从cursor字段中访问metrics 字段:

1
db.serverStatus().metrics.cursor

结果是以下文档:

1
2
3
4
5
6
7
8
{
   "timedOut" : <number>
   "open" : {
      "noTimeout" : <number>,
      "pinned" : <number>,
      "total" : <number>
   }
}