返回存储的源字段
如果在某个集合的索引定义 中配置了 storedSource 选项,Atlas Search 会将指定字段存储在mongot
中。您可以在 Atlas Search 查询中使用 returnStoredSource
布尔值选项来仅检索这些字段,而不是从集合中获取完整文档。
默认情况下,Atlas Search 为查询匹配文档后,Atlas Search 会隐式对后端数据库执行完整文档查找。 此查找可能会严重降低后续聚合管道阶段的性能,这些阶段会从$search
阶段获取所有匹配的数据集(例如 $sort
、 $group
)或筛选其中的很大一部分(例如$match
、 $skip
)。 如果配置了storedSource
选项,则可以使用returnStoredSource
选项,仅检索直接存储在 Atlas Search 上的文档的部分内容,避免在数据库中查找完整文档。 这允许您使用最少数量的字段对文档执行大多数数据库端筛选操作。 然后,您可以在管道的后续阶段使用$lookup
从文档中检索所有字段。
注意
returnStoredSource
仅适用于运行 MongoDB 5.0 及更高版本的 Atlas 集群。对于分片集合,
$lookup
仅适用于运行 MongoDB 5.1及更高版本的 Atlas 集群。
语法
returnStoredSource
查询中包含以下语法:
{ $search: { "<operator>": { <operator-specification> }, "returnStoredSource": true | false // optional, defaults to "false" } }
要了解有关查询语法的更多信息,请参阅$search
。
行为
returnStoredSource
布尔选项指定 Atlas Search 是否必须对数据库执行完整文档查找,还是直接从 Atlas Search 返回存储的字段。仅当索引定义包含在 Atlas Search 上存储字段的配置时,才能使用returnStoredSource
选项。要了解有关在 Atlas Search 上存储字段的更多信息,请参阅查看 Atlas Search 索引语法和在 Atlas Search 索引中定义存储的源字段。
您可以为returnStoredSource
选项设置以下值之一:
true
- 仅返回直接从 Atlas Search 中存储的源字段false
— 对后端数据库执行隐式完整文档查找(默认)
如果您在将returnStoredSource
布尔选项设置为true
的情况下运行 Atlas Search 搜索查询:
如果文档不包含配置用于存储的字段,Atlas Search 将返回空文档。
如果索引定义不包含“存储的源”配置,Atlas Search 将返回错误。
由于复制延迟,Atlas Search 可能会返回过时的数据。
Atlas Search 可能会返回有关分片集群的重复数据。
如果您在后端数据库上对集合执行高容量和高速率的数据插入和更新操作,则 Atlas Search 可能会返回过时的数据,因为存储在 mongot
上的数据可能由于复制延迟而不是最新的。您可以从 Atlas 用户界面中 mongod
的 oplog 中查看 Atlas Search 在复制更改时大约落后的毫秒数。要了解更多信息,请参阅查看 Atlas Search 指标。
如果在数据段迁移过程中出现孤立文档,Atlas Search 可能会为针对分片集群的查询返回重复文档。
使用示例
如果您的$search
阶段丢弃了大量结果,而您需要对数据库执行隐式文档查找,我们建议使用returnStoredSource
选项。 您可以存储排序或筛选所需的字段,并在查询时使用returnStoredSource
选项来执行以下操作:
对 Atlas Search 返回的部分文档进行中间操作
$lookup
如果需要完整的文档,则在管道末端。
重要
为了提高效率,请仅在 Atlas Search 上配置最少数量的存储字段。如果您的文档大到足以在查找期间导致问题,请使用此选项。
示例
本部分中的示例使用sample_mflix.movies
collection。这些示例展示了如何对 Atlas Search 在$search
阶段后返回的文档进行排序或匹配,然后在数据库中查找文档。
使用以下索引定义创建索引。 collection的索引定义指定以下字段:
索引
title
字段存储
year
和title
字段
{ "mappings": { "fields": { "title": { "type": "string" } } }, "storedSource": { "include": [ "year", "title" ] } } 对collection运行以下查询:
db.movies.aggregate([ { // search and output documents $search: { "text": { "query": "baseball", "path": "title" }, "returnStoredSource": true // return stored fields only } }, // fetch all matched dataset from $search stage and sort it { $sort: {"year": 1, "title": 1} }, // discard everything except top 10 results { $limit: 10 }, // perform full document lookup for top 10 documents only { $lookup: { from: "movies", localField: "_id", foreignField: "_id", as: "document" } } ]) 该查询返回以下文档:
1 [ 2 { 3 _id: ObjectId("573a1399f29313caabced370"), 4 title: 'Mr. Baseball', 5 year: 1992, 6 document: [ 7 { ... } // full document returned by $lookup 8 ] 9 }, 10 { 11 _id: ObjectId("573a1399f29313caabcee1aa"), 12 title: 'Baseball', 13 year: 1994, 14 document: [ 15 { ... } // full document returned by $lookup 16 ] 17 } 18 ]
使用以下索引定义创建索引。 collection的索引定义指定以下字段:
索引
title
字段存储
imdb.rating
和imdb.votes
字段
{ "mappings": { "fields": { "title": { "type": "string" } } }, "storedSource": { "include": [ "imdb.rating", "imdb.votes" ] } } 对collection运行以下查询:
db.movies.aggregate([ { // search and output documents $search: { "text": { "query": "baseball", "path": "title" }, "returnStoredSource": true // return stored fields only } }, // filter dataset from $search stage using $match { $match: {$or: [ { "imdb.rating": { $gt: 8.2 } }, { "imdb.votes": { $gte: 4500 } } ]} }, // perform full document lookup for matched documents only { $lookup: { from: "movies", localField: "_id", foreignField: "_id", as: "document" } } ]) 该查询返回以下文档:
1 [ 2 { 3 _id: ObjectId("573a1399f29313caabcee1aa"), 4 imdb: { rating: 9.1, votes: 2460 }, 5 document: [ 6 { ... } // full document returned by $lookup 7 ] 8 }, 9 { 10 _id: ObjectId("573a1399f29313caabced370"), 11 imdb: { rating: 5.8, votes: 7617 }, 12 document: [ 13 { ... } // full document returned by $lookup 14 ] 15 } 16 ]