您可以在 视图上创建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搜索索引。针对该视图运行MongoDB搜索查询。
限制
MongoDB Search 支持具有以下阶段的视图:
索引名称在源集合及其所有视图中必须是唯一的。
MongoDB Search 不支持会生成动态结果的操作符的视图定义,例如$$USER_ROLES系统变量和$rand聚合操作符。
MongoDB Search 查询会返回源集合中出现的原始文档。
要检索已转换的文档,请使用
storedSource选项。
所需权限
要创建视图,您的角色必须具有createCollection 权限。
示例
以下示例演示了如何创建视图、对文档进行部分索引以及使用索引对视图运行查询。
您可以使用过滤器筛选文档以对集合进行部分索引。以下示例在 sample_mflix.movies 集合上创建一个视图,以便您可以仅搜索在 2000 年 1 月 1 日之后发行的电影。
使用mongosh 连接到您的集群。
要学习;了解更多信息,请参阅通过mongosh连接到集群。
在Atlas中,转到项目的Clusters 页面。
如果尚未显示,请从导航栏上的 Organizations 菜单中选择包含所需项目的组织。
如果尚未显示,请从导航栏的Projects菜单中选择所需的项目。
在侧边栏中,单击 Database 标题下的 Clusters。
会显示集群页面。
在Atlas中,转到集群的Search & Vector Search 页面。
您可以从 Search & Vector Search 选项或 Data Explorer go 到 MongoDB搜索页面。
如果尚未显示,请从导航栏上的 Organizations 菜单中选择包含项目的组织。
如果尚未显示,请从导航栏的 Projects 菜单中选择您的项目。
在侧边栏中,单击 Database 标题下的 Search & Vector Search。
如果没有集群,则请单击 Create cluster 来创建一个。要了解更多信息,请参阅创建集群。
如果您的项目有多个集群,请从 Select cluster 下拉列表中选择要使用的集群,然后单击 Go to Search。
开始您的索引配置。
在页面上进行以下选择,然后单击 Next。
Search Type | 选择 MongoDB Search 索引类型。 |
Index Name and Data Source | 指定以下信息:
|
Configuration Method | For a guided experience, select Visual Editor. To edit the raw index definition, select JSON Editor. |
重要提示:
默认下, MongoDB Search索引名为 default。如果保留此名称,则该索引将是任何未在运算符中指定其他 index 选项的MongoDB搜索查询的默认搜索索引。如果您要创建多个索引,我们建议您在所有索引之间保持一致的描述性命名约定。
查询releasedAfter2000Index 部分索引。
注意
以下示例通过对名为 movies_ReleasedAfter2000 的视图运行 .aggregate 命令来查询 releasedAfter2000Index 索引。如果您的集群正在运行 MongoDB v8.0,则必须使用视图上的索引查询源集合(例如,movies)。升级到 MongoDB v8.1+ 以直接查询视图。
[ { "$search": { "index": "releasedAfter2000Index", "text": { "path": "title", "query": "foo" }, "sort": { "released": 1 } } } ]
SCORE: 3.120296001434326 _id: “573a13d2f29313caabd929f8” awards: Object cast: Array (4) countries: Array (1) directors: Array (1) fullplot: "Rising from the ashes of Nirvana, the Foo Fighters became a Grammy-win…" genres: Array (2) imdb: Object languages: Array (1) lastupdated: "2015-08-19 00:00:25.937000000" num_mflix_comments: 0 plot: "Rising from the ashes of Nirvana, the Foo Fighters became a Grammy-win…" poster: "https://m.media-amazon.com/images/M/MV5BMzE4OTczMTgxM15BMl5BanBnXkFtZT…" released: 2011-04-05T00:00:00.000+00:00 runtime: 150 title: "Foo Fighters: Back and Forth" tomatoes: Object type: "movie" year: 2011
使用 连接到MongoDB部署。mongosh
要学习;了解更多信息,请参阅通过mongosh连接到集群。
查询releasedAfter2000Index 部分索引。
注意
以下示例通过对名为 movies_ReleasedAfter2000 的视图运行 .aggregate 命令来查询 releasedAfter2000Index 索引。如果您的集群正在运行 MongoDB v8.0,则必须使用视图上的索引查询源集合(例如,movies)。升级到 MongoDB v8.1+ 以直接查询视图。
db.movies_ReleasedAfter2000.aggregate([ { $search: { index: "releasedAfter2000Index", text: { path: "title", query: "foo" }, sort: { released: 1 } } } ])
[ { _id: ObjectId('573a13d2f29313caabd929f8'), plot: "Rising from the ashes of Nirvana, the Foo Fighters became a Grammy-winning sensation on their own. Sixteen years of the band's history comes to life in this documentary, from their demo ...", genres: [ 'Documentary', 'Music' ], runtime: 150, cast: [ 'Shawn Cloninger', 'William Goldsmith', 'Jessy Greene', 'Dave Grohl' ], num_mflix_comments: 0, poster: 'https://m.media-amazon.com/images/M/MV5BMzE4OTczMTgxM15BMl5BanBnXkFtZTcwNTU1NjQxOA@@._V1_SY1000_SX677_AL_.jpg', title: 'Foo Fighters: Back and Forth', fullplot: `Rising from the ashes of Nirvana, the Foo Fighters became a Grammy-winning sensation on their own. Sixteen years of the band's history comes to life in this documentary, from their demo tapes through the creation of their 2011 album, "Wasting Light."`, languages: [ 'English' ], released: ISODate('2011-04-05T00:00:00.000Z'), directors: [ 'James Moll' ], awards: { wins: 1, nominations: 1, text: '1 win & 1 nomination.' }, lastupdated: '2015-08-19 00:00:25.937000000', year: 2011, imdb: { rating: 8.4, votes: 3745, id: 1853563 }, countries: [ 'USA' ], type: 'movie', tomatoes: { viewer: { rating: 4.4, numReviews: 857, meter: 96 }, dvd: ISODate('2011-08-08T00:00:00.000Z'), website: 'http://us.foofightersfilm.com/', production: 'Cinedigm Digital Cinema', lastUpdated: ISODate('2015-09-12T18:42:01.000Z') } } ]
以下示例允许您根据新的 totalPrice字段在 sample_airbnb.listingsAndReviews集合中搜索住宿,该字段是 price 和 cleaningFee 字段的总和。此外,由于MongoDB Search 不支持Decimal128 类型,因此我们将值转换为 Double。
使用mongosh 连接到集群。
要学习;了解更多信息,请参阅通过mongosh连接到集群。
在Atlas中,转到项目的Clusters 页面。
如果尚未显示,请从导航栏上的 Organizations 菜单中选择包含所需项目的组织。
如果尚未显示,请从导航栏的Projects菜单中选择所需的项目。
在侧边栏中,单击 Database 标题下的 Clusters。
会显示集群页面。
在Atlas中,转到集群的Search & Vector Search 页面。
您可以从 Search & Vector Search 选项或 Data Explorer go 到 MongoDB搜索页面。
如果尚未显示,请从导航栏上的 Organizations 菜单中选择包含项目的组织。
如果尚未显示,请从导航栏的 Projects 菜单中选择您的项目。
在侧边栏中,单击 Database 标题下的 Search & Vector Search。
如果没有集群,则请单击 Create cluster 来创建一个。要了解更多信息,请参阅创建集群。
如果您的项目有多个集群,请从 Select cluster 下拉列表中选择要使用的集群,然后单击 Go to Search。
totalPriceIndex对 索引运行查询。
注意
以下示例通过对名为 listingsAndReviews_totalPrice 的视图运行 .aggregate 命令来查询 totalPriceIndex 索引。如果您的集群正在运行 MongoDB v8.0,则必须使用视图上的索引查询源集合(例如,listingsAndReviews)。升级到 MongoDB v8.1+ 以直接查询视图。
[ { "$search": { "index": "totalPriceIndex", "range": { "path": "totalPrice", "lte": 300 }, "returnStoredSource": true } } ]
SCORE: 1 _id: "10006546" totalPrice: 115 SCORE: 1 _id: "1001265" totalPrice: 215 SCORE: 1 _id: "10021707" totalPrice: 40 SCORE: 1 _id: "1003530" totalPrice: 270 SCORE: 1 _id: "10038496" totalPrice: 269 SCORE: 1 _id: "10051164" totalPrice: 250 SCORE: 1 _id: "10057447" totalPrice: 50 SCORE: 1 _id: "10057826" totalPrice: 205 SCORE: 1 _id: "10059244" totalPrice: 43 SCORE: 1 _id: "10066928" totalPrice: 140
使用 连接到MongoDBmongosh 部署。
要学习;了解更多信息,请参阅通过mongosh连接到集群。
totalPriceIndex对 索引运行查询。
注意
以下示例通过对名为 listingsAndReviews_totalPrice 的视图运行 .aggregate 命令来查询 totalPriceIndex 索引。如果您的集群正在运行 MongoDB v8.0,则必须使用视图上的索引查询源集合(例如,listingsAndReviews)。升级到 MongoDB v8.1+ 以直接查询视图。
db.listingsAndReviews_totalPrice.aggregate([ { $search: { index: "totalPriceIndex", range: { path: "totalPrice", lte: 300 }, returnStoredSource: true } } ])
[ { _id: '10006546', totalPrice: 115 }, { _id: '1001265', totalPrice: 215 }, { _id: '10021707', totalPrice: 40 }, { _id: '1003530', totalPrice: 270 }, { _id: '10038496', totalPrice: 269 }, { _id: '10051164', totalPrice: 250 }, { _id: '10057447', totalPrice: 50 }, { _id: '10057826', totalPrice: 205 }, { _id: '10059244', totalPrice: 43 }, { _id: '10066928', totalPrice: 140 }, { _id: '10082422', totalPrice: 60 }, { _id: '10083468', totalPrice: 40 }, { _id: '10084023', totalPrice: 231 }, { _id: '10091713', totalPrice: 231 }, { _id: '10092679', totalPrice: 58 }, { _id: '10096773', totalPrice: 205 }, { _id: '10112159', totalPrice: 90 }, { _id: '10117617', totalPrice: 55 }, { _id: '10120414', totalPrice: 150 }, { _id: '10133554', totalPrice: 121 } ]
要对匹配命名模式的字段索引,请使用视图来转换数据,以便将要索引的字段嵌套在子文档中。这使您能够对子文档路径使用动态映射,以便您可以自动搜索后缀为_type 的所有新字段,而无需对索引定义进行任何更改。
以下名为View listings_SearchableTypes_type的 仅匹配sample_airbnb.listingsAndReviews 集合中以 结尾的字段名称。具体来说,$set 阶段添加了一个名为searchable_types 的新字段,其中包含字段名称中带有_type 术语的筛选字段。$arrayToObject 包含过滤输入(整个文档)和条件(_type 的正则表达式匹配项)。
使用mongosh 连接到您的集群。
要学习;了解更多信息,请参阅通过mongosh连接到集群。
创建一个名为listings_SearchableTypes 的视图。
1 db.createView( 2 "listings_SearchableTypes", 3 "listingsAndReviews", 4 [ 5 { 6 "$set": { 7 "searchable_types": { 8 "$arrayToObject": { 9 "$filter": { 10 "input": { "$objectToArray": "$$ROOT" }, 11 "cond": { 12 "$regexMatch": { 13 "input": "$$this.k", 14 "regex": /_type$/ 15 } 16 } 17 } 18 } 19 } 20 } 21 } 22 ] 23 )
在Atlas中,转到项目的Clusters 页面。
如果尚未显示,请从导航栏上的 Organizations 菜单中选择包含所需项目的组织。
如果尚未显示,请从导航栏的Projects菜单中选择所需的项目。
在侧边栏中,单击 Database 标题下的 Clusters。
会显示集群页面。
在Atlas中,转到集群的Search & Vector Search 页面。
您可以从 Search & Vector Search 选项或 Data Explorer go 到 MongoDB搜索页面。
如果尚未显示,请从导航栏上的 Organizations 菜单中选择包含项目的组织。
如果尚未显示,请从导航栏的 Projects 菜单中选择您的项目。
在侧边栏中,单击 Database 标题下的 Search & Vector Search。
如果没有集群,则请单击 Create cluster 来创建一个。要了解更多信息,请参阅创建集群。
如果您的项目有多个集群,请从 Select cluster 下拉列表中选择要使用的集群,然后单击 Go to Search。
编辑索引定义。
复制并粘贴以下索引定义以替换用户界面中的默认索引定义:
{ "analyzer": "lucene.standard", "searchAnalyzer": "lucene.standard", "mappings": { "dynamic": false, "fields": { "searchable_types": [ { "dynamic": { "typeSet": "tokenTypeSet" }, "type": "document" } ] } }, "typeSets": [ { "name": "tokenTypeSet", "types": [ { "type": "token" } ] } ] }
查询视图。
以下查询在名为 listings_SearchableTypes 的视图中搜索带有 private room 的 house。要运行此查询,请复制并粘贴查询,然后单击 Search:
[ { "$search": { "index": "listingsSearchableTypes", "compound": { "should": [ { "text": { "path": "searchable_types.property_type", "query": "House" } }, { "text": { "path": "searchable_types.room_type", "query": "Private room" } } ] } } } ]
SCORE: 2.0530142784118652 _id: "10051164" name: "Catete's Colonial Big Hause Room B", searchable_types: Object property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' SCORE: 2.0530142784118652 _id: "1016739" name: 'Private Room (2) in Guest House at Coogee Beach', searchable_types: Object property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' SCORE: 2.0530142784118652 _id: "10324377" name: 'Suíte em local tranquilo e seguro', searchable_types: Object property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' SCORE: 2.0530142784118652 _id: "1073607" name: 'Bright Inner West Terrace Value+', searchable_types: Object property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' SCORE: 2.0530142784118652 _id: "1077686" name: 'BALAT', searchable_types: Object property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' SCORE: 2.0530142784118652 _id: "10990260" name: 'The Executive Posh Room', searchable_types: Object property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' SCORE: 2.0530142784118652 _id: "10992286" name: 'Holoholo Inn: Rain Forest (Priv-2)', searchable_types: Object property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' SCORE: 2.0530142784118652 _id: "11396243" name: 'Beautiful Ensuite Room -Easy access to city', searchable_types: Object property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' SCORE: 2.0530142784118652 _id: "1145567" name: 'ROOM + ENSUITE INNER CITY MOD HOUSE', searchable_types: Object property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' SCORE: 2.0530142784118652 _id: "11464859" name: 'The Sassy Lilac Megan Love Room', searchable_types: Object property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed'
使用 连接到MongoDB部署。mongosh
要学习;了解更多信息,请参阅通过mongosh连接到集群。
在视图上创建MongoDB Search索引。
View 上名为 listingsSearchableTypes 的以下索引定义将 typeSet 配置为自动将 searchable_types文档中的所有字段索引为 string 类型。如果添加与此模式匹配的新字段, MongoDB Search 也会自动为这些字段索引。
db.listings_SearchableTypes.createSearchIndex( "listingsSearchableTypes", { "analyzer": "lucene.standard", "searchAnalyzer": "lucene.standard", "mappings": { "dynamic": false, "fields": { "searchable_types": [ { "type": "document", "dynamic": { "typeSet": "tokenTypeSet" } } ] } }, "typeSets": [ { "name": "tokenTypeSet", "types": [ { "type": "token" } ] } ] } )
totalPriceIndex对 索引运行查询。
注意
以下示例通过对名为 listings_SearchableTypes 的视图运行 .aggregate 命令来查询 listingsSearchableTypes 索引。如果您的集群正在运行 MongoDB v8.0,则必须使用视图上的索引查询源集合(例如,listingsAndReviews)。升级到 MongoDB v8.1+ 以直接查询视图。
以下查询在名为 listings_SearchableTypes 的视图中搜索带有 private room 的 house。
db.listings_SearchableTypes.aggregate([ { "$search": { "index": "listingsSearchableTypes", "compound": { "should": [ { "equals": { "path": "searchable_types.property_type", "value": "House" } }, { "equals": { "path": "searchable_types.room_type", "value": "Private room" } } ] } } }, { "$limit": 10 }, { "$project": { "_id": 0, "searchable_types": 1, "name": 1 } } ])
[ { name: "Catete's Colonial Big Hause Room B", searchable_types: { property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' } }, { name: 'Private Room (2) in Guest House at Coogee Beach', searchable_types: { property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' } }, { name: 'Suíte em local tranquilo e seguro', searchable_types: { property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' } }, { name: 'Bright Inner West Terrace Value+', searchable_types: { property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' } }, { name: 'BALAT', searchable_types: { property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' } }, { name: 'The Executive Posh Room', searchable_types: { property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' } }, { name: 'Holoholo Inn: Rain Forest (Priv-2)', searchable_types: { property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' } }, { name: 'Beautiful Ensuite Room -Easy access to city', searchable_types: { property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' } }, { name: 'ROOM + ENSUITE INNER CITY MOD HOUSE', searchable_types: { property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' } }, { name: 'The Sassy Lilac Megan Love Room', searchable_types: { property_type: 'House', room_type: 'Private room', bed_type: 'Real Bed' } } ]
编辑视图
以下示例更新了 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') ] } } } ]
性能考虑因素
当Atlas读取视图以过滤和转换源集合时,高度复杂的视图转换可能会导致性能下降。在这种情况下,请考虑创建物化视图以避免对Atlas造成额外的复制负载。为避免视图转换导致的查询延迟,可以直接查询源集合以检索原始文档。
故障排除
索引更改为 FAILED
在以下场景中,索引会更改为 FAILED 状态:
您在与MongoDB搜索不兼容的视图上创建的索引。
您编辑视图的方式不符合MongoDB搜索兼容性要求。
您删除或更改视图的源集合。
例如,如果一个视图是在另一个视图上创建的,并且将父视图源更改为另一个集合。
注意
如果一个视图是其他视图的后代,这一限制也同样适用。例如,您无法更改或移除所有后代所源自的源集合。
索引更改为 STALE
在以下场景中,索引会更改为 STALE 状态:
警告
如果在视图中定义的聚合管道与集合中的文档不兼容,搜索复制将失败。例如,如果 $toDouble 表达式对包含数组的文档字段进行操作,复制将失败。确保您的视图在处理集合中的所有文档时不会出错。
如果视图定义导致聚合失败,而索引为
READY,则索引变为STALE。解析文档或更改视图定义以使其不再失败后,索引将返回到READY。当为STALE时,索引仍然可查询。如果索引脱离oplog,则会触发索引重建。如果视图定义在索引为
BUILDING时导致聚合管道失败,则在修复文档之前,则索引生成将停滞。在您解析文档或更改视图定义后,索引将返回到READY,以确保不再失败。
您可以在 Atlas 用户界面的索引状态详情页面查看索引状态。
错误:$search 仅作为管道中的第一阶段有效
当您使用 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 Vector Search索引,请参阅将视图与MongoDB Vector Search结合使用。