如果您在集合的 索引定义 中配置了 StoredSource 选项,则MongoDB Search 会将指定字段存储在 mongot
上。您可以在MongoDB搜索查询中使用 returnStoredSource
布尔选项,仅检索这些字段,而不是从集合中获取完整文档。
默认下, MongoDB Search 为MongoDB匹配文档后,会对后端数据库隐式执行完整文档查找。此查找可能会严重降低后续聚合管道阶段的性能,这些阶段会从$search
阶段获取所有匹配的数据集(例如$sort
、$group
)或过滤其中的很大一部分(例如$match
、$skip
)。如果配置了 storedSource
选项,则可以使用 returnStoredSource
选项,仅检索直接存储在MongoDB Search 中的文档的部分内容,避免对数据库进行完整文档查找。这允许您使用最少数量的字段对文档执行大多数数据库端筛选操作。然后,您可以在管道的后续阶段使用 $lookup
从文档中检索所有字段。
注意
returnStoredSource
仅适用于运行MongoDB 7.0 及更高版本的集群。对于分片的集合,
$lookup
仅适用于运行MongoDB 5.1 及更高版本的集群。
语法
returnStoredSource
查询中包含以下语法:
{ $search: { "<operator>": { <operator-specification> }, "returnStoredSource": true | false // optional, defaults to "false" } }
要了解有关查询语法的更多信息,请参阅$search
。
行为
returnStoredSource
布尔选项指定MongoDB Search 是否必须对数据库执行完整文档查找,还是直接从MongoDB Search 返回存储的字段。仅当索引定义包含在MongoDB Search 上存储字段的配置时,才能使用 returnStoredSource
选项。要学习;了解有关在MongoDB Search 上存储字段的更多信息,请参阅索引参考资料和在MongoDB Search 索引中定义存储的源字段。
您可以为returnStoredSource
选项设置以下值之一:
true
- 仅返回直接从MongoDB Search 中存储的源字段false
— 对后端数据库执行隐式完整文档查找(默认)
如果在将 returnStoredSource
布尔选项设立为 true
的情况下运行MongoDB Search 查询:
如果文档不包含配置用于存储的字段,则MongoDB Search 返回空文档。
如果索引定义不包含“存储的源”配置, MongoDB Search 将返回错误。
由于复制延迟, MongoDB Search 可能会返回过时的数据。
MongoDB Search 可能会返回分片的集群的重复数据。
如果您在后端数据库上对集合执行大量高速率的数据插入和更新操作, MongoDB Search 可能会返回过时数据,因为由于复制延迟,存储在 mongot
上的数据可能不是最新的。您可以在Atlas 用户界面中查看MongoDBmongod
Search 从 的 oplog 复制更改时延迟的大致毫秒数。要学习;了解更多信息,请参阅查看MongoDB搜索指标。
如果在数据块迁移过程中出现孤立文档, MongoDB Search 可能会为针对分片集群的查询返回重复文档。
使用示例
如果您的$search
阶段丢弃了大量结果,而您需要对数据库执行隐式文档查找,我们建议使用returnStoredSource
选项。 您可以存储排序或筛选所需的字段,并在查询时使用returnStoredSource
选项来执行以下操作:
对MongoDB Search 返回的部分文档进行中间操作
$lookup
如果需要完整的文档,则在管道末端。
重要
为了效率,请仅在MongoDB Search 上配置最少数量的存储字段。如果您的文档大到足以在查找期间导致问题,请使用此选项。
示例
本节中的示例使用 sample_mflix.movies
集合。这些示例展示了如何对MongoDB搜索在 $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 ]