您可以在视图上创建 MongoDB Search 索引,以转换文档和集合,从而能够部分索引集合、支持不兼容的数据类型或数据模型等。
以下示例使用了 sample_mflix 和 sample_airbnb 示例数据库。
要求
您必须使用 MongoDB 8.0 或更高版本。
在 MongoDB v8.0+ 上:
使用Atlas用户界面或Atlas管理API在视图上创建MongoDB搜索索引。
对源集合运行MongoDB Search 查询。参考在视图上创建的MongoDB Search索引。 这些查询返回源集合中出现的原始文档。
在 MongoDB v8.1+ 上,您还可以:
使用
mongosh和 驱动程序 方法、db.collection.createSearchIndex()、db.collection.updateSearchIndex()、db.collection.dropSearchIndex()和$listSearchIndexes在视图上创建和管理MongoDB Search 索引。针对该视图运行MongoDB搜索查询。
在 MongoDB v8.2+ 上,您还可以:
在视图的聚合管道中使用
$rankFusion。使用
$lookup和$unionWith. 查询包含分片的子管道的查询视图。
限制
索引名称在源集合及其所有视图中必须是唯一的。
MongoDB Search 不支持会产生动态结果的操作符的视图定义,例如$$USER_ROLES系统变量和
$rand聚合操作符。MongoDB Search 查询会返回源集合中出现的原始文档。
- 要检索已转换的文档,请使用
storedSource选项。
所需权限
要创建视图,您的角色必须拥有 createCollection 权限。
示例
The following examples show how to create a view, create a partial index, and run queries that use the index. The examples query the index by running the .aggregate command against the source collection or the view. MongoDB Search supports queries on views directly only on MongoDB v8.1 or later.
您可以使用过滤器筛选文档以对集合进行部分索引。以下示例在 sample_mflix.movies 集合上创建一个视图,以便您可以仅搜索在 2000 年 1 月 1 日之后发行的电影。
The following example lets you search the sample_airbnb.listingsAndReviews collection for accommodations based on a new totalPrice field, which is the sum of the price and cleaningFee fields. Also, since MongoDB Search doesn't support Decimal128 types, the values need to be transformed to Double.
要索引与命名模式匹配的字段,请使用 视图 转换数据,使要索引的字段嵌套在子文档中。这样,您就可以使用子文档路径的动态映射,从而可以自动搜索带后缀 _type 的所有新字段,而无需更改索引定义。
以下 View 名为 listings_SearchableTypes 的仅匹配 sample_airbnb.listingsAndReviews 集合中以 _type 结尾的字段名称。具体来说,该 $set阶段添加了一个名为searchable_types 的新字段,其中包含字段名中含有_type 的过滤后字段。该 $arrayToObject包含过滤器输入(整个文档)和条件(与_type 匹配的 regex)。
对于 Decimal128 类型字段的搜索,我们建议将这些值转换为 double 类型。
以下示例在sample_airbnb.listingsAndReviews命名空间上创建一个视图,添加一个名为totalPrice的字段,该字段包含将price字段和cleaning_fee字段的值转换为double后的总和。
编辑视图
以下示例更新了 2000 年之前电影的 movies_ReleasedAfter2000 MongoDB 视图。
db.runCommand( { collMod: "movies_ReleasedAfter2000", viewOn: "movies", "pipeline": [ { $match: { $expr: { $lt: [ "$released", ISODate("2000-01-01T00") ] } } } ] } )
运行此命令后,MongoDB Search 会自动检测视图定义中的更改,并执行重新索引,而不会造成停机。
返回视图的管道
以下示例返回 movies_ReleasedAfter2000 视图中的管道。
db.getCollectionInfos({ name: "movies_ReleasedAfter2000" })[0].options.pipeline
[ { '$match': { '$expr': { '$gt': [ '$released', ISODate('2000-01-01T00:00:00.000Z') ] } } } ]
性能考虑因素
高度复杂的视图转换会增加索引和查询时间。这是因为mongod 在索引期间(初始同步和稳态复制)筛选和转换oplog条目时,以及在查询时将这些转换应用于返回的文档时,必须读取视图定义。
请考虑创建物化视图以避免Atlas上的额外的复制负载。您还可以直接查询源集合,以避免视图转换造成的查询延迟。
故障排除
索引更改为 FAILED
在以下场景中,索引会更改为 FAILED 状态:
您在与MongoDB搜索不兼容的视图上创建的索引。
您编辑视图的方式不符合MongoDB搜索兼容性要求。
您删除或更改视图的源集合。
例如,如果一个视图是在另一个视图上创建的,并且将父视图源更改为另一个集合。
注意
如果一个视图是其他视图的后代,这一限制也同样适用。例如,您无法更改或移除所有后代所源自的源集合。
索引更改为 STALE
在以下场景中,索引会更改为 STALE 状态:
警告
如果在视图中定义的聚合管道与集合中的文档不兼容,搜索复制将失败。例如,如果 $toDouble 表达式对包含数组的文档字段进行操作,复制将失败。确保您的视图在处理集合中的所有文档时不会出错。
如果视图定义导致聚合失败,而索引为
READY,则索引变为STALE。解析文档或更改视图定义以使其不再失败后,索引将返回到READY。当为STALE时,索引仍然可查询。如果索引脱离oplog,则会触发索引重建。如果视图定义在索引为
BUILDING时导致聚合管道失败,则在修复文档之前,则索引生成将停滞。在您解析文档或更改视图定义后,索引将返回到READY,以确保不再失败。
您可以在 Atlas 用户界面的索引状态详情页面查看索引状态。
Error: $search is only valid as the first stage in a pipeline
当您使用 8.1 之前的MongoDB版本查询视图时,会出现此错误。
如果您使用 8.0 之前的MongoDB版本,我们建议您升级到 8.1+ 以直接查询视图。您可以升级到 8.0 来查询源集合。
如果使用MongoDB 8.0,则必须针对源集合查询视图索引。示例,对集合而不是视图运行
.aggregate()。
索引流程
当您在视图上创建MongoDB搜索索引时,mongot进程执行的任务与您在常规集合上创建MongoDB搜索索引时相同。mongot进程:
根据集合索引定义中的规则创建MongoDB Search 索引。
监控变更流以了解您定义了MongoDB Search 索引的集合的文档和索引的当前状态。
处理MongoDB搜索查询,并将匹配文档的文档ID 和其他搜索元数据返回给
mongod,后者执行完整文档查找并将结果返回给客户端。
当您在视图上创建MongoDB搜索索引时,会在步骤 1 和 2 期间应用视图定义,并且转换后的文档会根据搜索索引定义进行索引,然后存储在磁盘上。
了解详情
要了解有关视图的更多信息,请参阅视图。
要在视图上创建MongoDB 向量搜索索引,请参阅将视图与MongoDB 向量搜索 结合使用。