Docs 菜单
Docs 主页
/
MongoDB Atlas
/ / / /

嵌入式文档

在此页面上

  • 定义
  • 语法
  • 选项
  • 行为
  • 评分行为
  • 排序行为
  • 突出显示
  • 限制
  • 示例
  • 索引定义
  • 基本查询
  • 分面查询
  • 查询和排序
  • 仅查询匹配的嵌入式文档

注意

Atlas Search embeddedDocuments 类型、 embeddedDocument 操作符和 embedded 评分选项正在预览中。当副本集或单个 MongoDB 分片上的 Atlas Search 索引达到 2,100,000,000 个索引对象时,Atlas Search 会将索引转换为失败、不可查询的状态。当此功能正式可用时,将制定适应此限制的解决方案。要解决与使用此功能有关的任何问题,请与支持部门联系。要请求对超过 2,100,000,000 个索引对象的支持,请在 MongoDB 反馈引擎中投票支持此请求

embeddedDocument

embeddedDocument 操作符与 $elemMatch 操作符类似。它限定嵌入式文档数组的单个元素满足多个查询谓词。embeddedDocument 只能用于查询 embeddedDocuments 类型的字段。

embeddedDocument 通过以下语法实现:

{
"embeddedDocument": {
"path": "<path-to-field>",
"operator": { <operator-specification> },
"score": { <score-options> }
}
}

embeddedDocument 使用以下选项构建查询:

字段
类型
说明
必要性
operator
对象
用于查询您在 path 中指定的文档数组中的每个文档的操作符。不支持 moreLikeThis 操作符。
必需
path
字符串
要搜索的索引 embeddedDocuments 类型字段。指定的字段必须是使用 operator 选项指定的所有操作符和字段的父字段。有关更多信息,请参阅路径构建
必需
score
对象
分配给匹配Atlas Search结果的分数。 您可以使用embedded评分选项来配置评分选项。 要了解更多信息,请参阅对行为进行评分。
Optional

当您使用 embeddedDocument 操作符查询数组中的嵌入式文档时,Atlas Search 会在查询执行的不同阶段对运算符查询谓词进行评估和评分。Atlas Search:

  1. 独立评估数组中的每个嵌入式文档。

  2. 合并使用 embedded 选项配置的匹配结果的分数;如果未指定 embedded 分数选项,则汇总以合并匹配结果的分数。

  3. 如果通过 compound 操作符指定了其他查询谓词,则将匹配结果与父文档连接在一起。

    注意

    对于字符串分面,Atlas Search 会对结果集中的每个文档计数一次字符串分面。有关此行为的示例,请参见示例

默认情况下,embeddedDocument 操作符使用默认聚合策略 (sum) 合并嵌入式文档匹配的分数。embeddedDocument 操作符 score 选项允许您覆盖默认值,并使用 embedded 选项配置匹配结果的分数。

提示

另请参阅:

要按嵌入式文档字段对父文档进行排序,必须执行以下操作:

  • 将嵌入式文档子字段的父项索引为文档类型。

  • 将嵌入文档中带有 string 值的子字段索引为标记类型。对于带有数字和日期值的子字段,启用动态映射可自动为这些字段编制索引。

Atlas Search 仅对父文档进行排序。它不对文档数组中的子字段进行排序。有关示例,请参阅排序示例。

对于在 embeddedDocument 操作符中指定的查询谓词,如果字段根据 document 类型的父字段进行索引,您可以突出显示这些字段。有关示例,请参阅教程

您无法突出显示 embeddedDocument 操作符中的查询。

以下示例使用了示例数据集中的 sample_supplies.sales 集合。

这些示例查询对集合使用以下索引定义:

{
"mappings": {
"dynamic": true,
"fields": {
"items": [
{
"dynamic": true,
"type": "embeddedDocuments"
},
{
"dynamic": true,
"fields": {
"tags": {
"type": "token"
}
},
"type": "document"
}
],
"purchaseMethod": {
"type": "stringFacet"
}
}
}
}

以下查询在集合中搜索标记为school的项目,并优先搜索名为backpack的项目。 Atlas Search 根据所有匹配嵌入式文档的平均分数(算术平均值)按降序对结果进行评分。 该查询包括一个用于将输出限制为5文档的$limit阶段和一个用于执行以下操作的$project阶段:

  • 排除 items.nameitems.tags 字段以外的所有字段

  • 添加字段 score

1db.sales.aggregate({
2 "$search": {
3 "embeddedDocument": {
4 "path": "items",
5 "operator": {
6 "compound": {
7 "must": [{
8 "text": {
9 "path": "items.tags",
10 "query": "school"
11 }
12 }],
13 "should": [{
14 "text": {
15 "path": "items.name",
16 "query": "backpack"
17 }
18 }]
19 }
20 },
21 "score": {
22 "embedded": {
23 "aggregate": "mean"
24 }
25 }
26 }
27 }
28},
29{
30 $limit: 5
31},
32{
33 $project: {
34 "_id": 0,
35 "items.name": 1,
36 "items.tags": 1,
37 "score": { $meta: "searchScore" }
38 }
39})
[
{
items: [ {
name: 'backpack',
tags: [ 'school', 'travel', 'kids' ]
} ],
score: 1.2907354831695557
},
{
items: [ {
name: 'envelopes',
tags: [ 'stationary', 'office', 'general' ]
},
{
name: 'printer paper',
tags: [ 'office', 'stationary' ]
},
{
name: 'backpack',
tags: [ 'school', 'travel', 'kids' ]
} ],
score: 1.2907354831695557
},
{
items: [ {
name: 'backpack',
tags: [ 'school', 'travel', 'kids' ]
} ],
score: 1.2907354831695557
},
{
items: [ {
name: 'backpack',
tags: [ 'school', 'travel', 'kids' ]
} ],
score: 1.2907354831695557
},
{
items: [ {
name: 'backpack',
tags: [ 'school', 'travel', 'kids' ]
} ],
score: 1.2907354831695557
}
]

以下查询搜索标记为 school 且优先搜索名为 backpack 的项目。它请求有关 purchaseMethod 字段的分面信息。

1db.sales.aggregate({
2 "$searchMeta": {
3 "facet": {
4 "operator": {
5 "embeddedDocument": {
6 "path": "items",
7 "operator": {
8 "compound": {
9 "must": [
10 {
11 "text": {
12 "path": "items.tags",
13 "query": "school"
14 }
15 }
16 ],
17 "should": [
18 {
19 "text": {
20 "path": "items.name",
21 "query": "backpack"
22 }
23 }
24 ]
25 }
26 }
27 }
28 },
29 "facets": {
30 "purchaseMethodFacet": {
31 "type": "string",
32 "path": "purchaseMethod"
33 }
34 }
35 }
36 }
37})
[
{
count: { lowerBound: Long("2309") },
facet: {
purchaseMethodFacet: {
buckets: [
{ _id: 'In store', count: Long("2751") },
{ _id: 'Online', count: Long("1535") },
{ _id: 'Phone', count: Long("578") }
]
}
}
}
]

以下查询搜索名为 laptop 的项目,并按 items.tags 字段对结果进行排序。该查询包括一个 $limit 阶段,用于将输出限制为 5 个文档,以及一个 $project 阶段,用于:

  • 排除 items.nameitems.tags 之外的所有字段

  • 添加字段 score

1db.sales.aggregate({
2 "$search": {
3 "embeddedDocument": {
4 "path": "items",
5 "operator": {
6 "text": {
7 "path": "items.name",
8 "query": "laptop"
9 }
10 }
11 },
12 "sort": {
13 "items.tags": 1
14 }
15 }
16},
17{
18 "$limit": 5
19},
20{
21 "$project": {
22 "_id": 0,
23 "items.name": 1,
24 "items.tags": 1,
25 "score": { "$meta": "searchScore" }
26 }
27})
1[
2 {
3 items: [
4 { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ] },
5 { name: 'binder', tags: [ 'school', 'general', 'organization' ] },
6 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
7 { name: 'laptop', tags: [ 'electronics', 'school', 'office' ] },
8 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
9 { name: 'printer paper', tags: [ 'office', 'stationary' ] },
10 { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] },
11 { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] },
12 { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ] }
13 ],
14 score: 1.168686032295227
15 },
16 {
17 items: [
18 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
19 { name: 'binder', tags: [ 'school', 'general', 'organization' ] },
20 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
21 { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] },
22 { name: 'printer paper', tags: [ 'office', 'stationary' ] },
23 { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] },
24 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
25 { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] },
26 { name: 'laptop', tags: [ 'electronics', 'school', 'office' ] }
27 ],
28 score: 1.168686032295227
29 },
30 {
31 items: [
32 { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] },
33 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
34 { name: 'binder', tags: [ 'school', 'general', 'organization' ] },
35 { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] },
36 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
37 { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ] },
38 { name: 'laptop', tags: [ 'electronics', 'school', 'office' ] }
39 ],
40 score: 1.168686032295227
41 },
42 {
43 items: [
44 { name: 'laptop', tags: [ 'electronics', 'school', 'office' ] },
45 { name: 'binder', tags: [ 'school', 'general', 'organization' ] },
46 { name: 'binder', tags: [ 'school', 'general', 'organization' ] },
47 { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] },
48 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
49 { name: 'printer paper', tags: [ 'office', 'stationary' ] },
50 { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] },
51 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
52 { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] },
53 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] }
54 ],
55 score: 1.168686032295227
56 },
57 {
58 items: [
59 { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ] },
60 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
61 { name: 'notepad', tags: [ 'office', 'writing', 'school' ] },
62 { name: 'backpack', tags: [ 'school', 'travel', 'kids' ] },
63 { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ] },
64 { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ] },
65 { name: 'binder', tags: [ 'school', 'general', 'organization' ] },
66 { name: 'laptop', tags: [ 'electronics', 'school', 'office' ] },
67 { name: 'printer paper', tags: [ 'office', 'stationary' ] },
68 { name: 'binder', tags: [ 'school', 'general', 'organization' ] }
69 ],
70 score: 1.168686032295227
71 }
72]

以下查询仅返回与查询匹配的嵌套文档。该查询在 $search 阶段使用 Atlas Search 复合操作符子句查找匹配的文档,然后在 $project阶段使用聚合操作符 以仅返回匹配的嵌入式文档。具体来说,该查询指定了以下管道阶段:

复合操作符 must 子句中指定以下条件:

  • 检查集合中是否存在 items.price 字段。

  • items.tags 字段中搜索标记为 office 的项目。

  • 仅当 items.quantity 字段的值大于 2 时才匹配。

将输出限制为 5 份文档。

请执行以下操作:

  • 排除 _id 字段,仅包含 itemsstoreLocation 字段。

  • 使用 $filter 以只返回 items 输入数组中符合 $and 操作符指定条件的元素。and 操作符使用以下操作符:

    • $ifNull 以确定 items.price 是否包含 null 值,并将 null 值(如果存在)替换为替换表达式 false

    • $gt 检查数量是否大于 2。

    • $in 来检查 office 是否存在于 tags 数组中。

1db.sales.aggregate(
2 {
3 "$search": {
4 "embeddedDocument": {
5 "path": "items",
6 "operator": {
7 "compound": {
8 "must": [
9 {
10 "range": {
11 "path": "items.quantity",
12 "gt": 2
13 }
14 },
15 {
16 "exists": {
17 "path": "items.price"
18 }
19 },
20 {
21 "text": {
22 "path": "items.tags",
23 "query": "school"
24 }
25 }
26 ]
27 }
28 }
29 }
30 }
31 },
32 {
33 "$limit": 2
34 },
35 {
36 "$project": {
37 "_id": 0,
38 "storeLocation": 1,
39 "items": {
40 "$filter": {
41 "input": "$items",
42 "cond": {
43 "$and": [
44 {
45 "$ifNull": [
46 "$$this.price", "false"
47 ]
48 },
49 {
50 "$gt": [
51 "$$this.quantity", 2
52 ]
53 },
54 {
55 "$in": [
56 "office", "$$this.tags"
57 ]
58 }
59 ]
60 }
61 }
62 }
63 }
64 }
65)
1[
2 {
3 storeLocation: 'Austin',
4 items: [
5 {
6 name: 'laptop',
7 tags: [ 'electronics', 'school', 'office' ],
8 price: Decimal128('753.04'),
9 quantity: 3
10 },
11 {
12 name: 'pens',
13 tags: [ 'writing', 'office', 'school', 'stationary' ],
14 price: Decimal128('19.09'),
15 quantity: 4
16 },
17 {
18 name: 'notepad',
19 tags: [ 'office', 'writing', 'school' ],
20 price: Decimal128('30.23'),
21 quantity: 5
22 },
23 {
24 name: 'pens',
25 tags: [ 'writing', 'office', 'school', 'stationary' ],
26 price: Decimal128('20.05'),
27 quantity: 4
28 },
29 {
30 name: 'notepad',
31 tags: [ 'office', 'writing', 'school' ],
32 price: Decimal128('22.08'),
33 quantity: 3
34 },
35 {
36 name: 'notepad',
37 tags: [ 'office', 'writing', 'school' ],
38 price: Decimal128('21.67'),
39 quantity: 4
40 }
41 ]
42 },
43 {
44 storeLocation: 'Austin',
45 items: [
46 {
47 name: 'notepad',
48 tags: [ 'office', 'writing', 'school' ],
49 price: Decimal128('24.16'),
50 quantity: 5
51 },
52 {
53 name: 'notepad',
54 tags: [ 'office', 'writing', 'school' ],
55 price: Decimal128('28.04'),
56 quantity: 5
57 },
58 {
59 name: 'notepad',
60 tags: [ 'office', 'writing', 'school' ],
61 price: Decimal128('21.42'),
62 quantity: 5
63 },
64 {
65 name: 'laptop',
66 tags: [ 'electronics', 'school', 'office' ],
67 price: Decimal128('1540.63'),
68 quantity: 3
69 },
70 {
71 name: 'pens',
72 tags: [ 'writing', 'office', 'school', 'stationary' ],
73 price: Decimal128('29.43'),
74 quantity: 5
75 },
76 {
77 name: 'pens',
78 tags: [ 'writing', 'office', 'school', 'stationary' ],
79 price: Decimal128('28.48'),
80 quantity: 5
81 }
82 ]
83 }
84]

提示

要在结果中只返回匹配的内嵌文档,请在内嵌文档字段中加入等效的 $filter 以匹配 $search 标准。要在 $search 阶段结果中只返回匹配的嵌入文档,请在 MongoDB 反馈引擎中投票支持此请求

后退

多个子句