定义
$meta返回与文档关联的元数据,例如执行文本搜索时返回
"textScore"。A
$metaexpression has the following syntax:{ $meta: <metaDataKeyword> } The
$metaexpression can specify the following values as the<metaDataKeyword>:Keyword说明"textScore"返回与每份匹配文档相应的
$text查询关联的得分。文本得分表示文档与搜索词的匹配程度。{ $meta: "textScore" }必须与$text查询结合使用。在早期版本中,如果不与
$text查询结合使用,返回的分数为空值。$textprovides text query capabilities for self-managed (non-Atlas) deployments. For data hosted on MongoDB Atlas, MongoDB offers an improved full-text query solution, Atlas Search."indexKey"如果使用非文本索引,则返回文档的索引键。
{ $meta: "indexKey" }表达式仅用于调试目的,不用于应用程序逻辑,并且比cursor.returnKey()更受青睐。MongoDB Atlas Search 提供其他
$meta关键字,例如:"searchSequenceToken" (Available starting in MongoDB 7.0.5 and 6.0.13)
有关详细信息,请参阅 Atlas Search 文档。
重要
Stable API V1 不支持以下
$meta关键字:"textScore""indexKey""searchScore""searchHighlights"(从 MongoDB 7.0.5 和 6.0.13 开始可用)"searchSequenceToken""searchScoreDetails"
行为
文本分数元数据 $meta: "textScore"
需要 $text 搜索
{ $meta: "textScore" }表达式必须与$text结合使用。例如:在查找中,必须在查询谓词中指定
$text操作符,才能使用{ $meta: "textScore" }。如果未在查询谓词中指定$text操作符,则操作失败。
注意
$textprovides text query capabilities for self-managed (non-Atlas) deployments. For data hosted on MongoDB Atlas, MongoDB offers an improved full-text query solution, Atlas Search.
可用性
投影中的使用
按文本分数筛选
聚合时,在输出文本分数值字段的阶段之后,可以在后续阶段指定查询条件或对字段进行操作。例如,请参阅自管理部署中的聚合管道中的 $text。
在查找中,不能对文本得分指定查询条件。请改用聚合。
排序使用
"textScore"元数据按降序排序。要在排序操作中使用,可将
{ $meta: "textScore" }表达式设置为任意字段名称。查询系统会忽略字段名称。
不使用投影进行排序
聚合时,可以按
{ $meta: "textScore" }对结果文档进行排序,而无需投影textScore。在查找中,您可以按
{ $meta: "textScore" }对结果文档进行排序,而无需投影textScore。
使用投影进行排序
In aggregation, if you include the
{ $meta: "textScore" }expression in both the projection and sort, the projection and sort can have different field names for the expression. The field name in the sort is disregarded by the query system.In find, if you include the
{ $meta: "textScore" }expression in both the projection and sort, the projection and sort can have different field names for the expression. The field name in the sort is disregarded by the query system.
索引键元数据 $meta: "indexKey"(聚合和查找)
使用
{ $meta: "indexKey" }表达式仅用于调试目的,不适用于应用程序逻辑。{ $meta: "indexKey" }表达式优先于cursor.returnKey()。
可用性
聚合时,
{ $meta: "indexKey" }表达式可以包含在接受聚合表达式的各个阶段,例如$project、$group、$sortByCount等,但不包含$sort。但是,使用聚合管道,可以先投影{ $meta: "indexKey" }表达式(例如在$project、$addFields等中),然后在后续$sort阶段按该字段排序。在查找中,
{ $meta: "indexKey" }表达式只能作为投影文档的一部分使用。
返回值
返回的值取决于数据库在索引中表示值的方式,并且可能会因版本而异。所表示的值可能不是该字段的实际值。
返回的值取决于系统选择的执行计划。例如,如果有两个可能用于回答查询的索引,那么“indexKey”元数据的值取决于选择了哪个索引。
如果未使用索引,则
{ $meta: "indexKey" }表达式不会返回值,并且该字段不会作为输出的一部分。
示例
$meta: "textScore"
使用以下文档创建 articles 集合:
db.articles.insertMany([ { "_id" : 1, "title" : "cakes and ale" }, { "_id" : 2, "title" : "more cakes" }, { "_id" : 3, "title" : "bread" }, { "_id" : 4, "title" : "some cakes" }, { "_id" : 5, "title" : "two cakes to go" }, { "_id" : 6, "title" : "pie" } ])
在 title 字段上创建文本索引:
db.articles.createIndex( { title: "text"} )
The following aggregation operation performs a text search and uses the $meta operator to group by the text search score:
db.articles.aggregate( [ { $match: { $text: { $search: "cake" } } }, { $group: { _id: { $meta: "textScore" }, count: { $sum: 1 } } } ] )
操作返回以下结果:
{ "_id" : 0.75, "count" : 1 } { "_id" : 0.6666666666666666, "count" : 1 } { "_id" : 1, "count" : 2 }
有关更多示例,请参阅自管理部署聚合管道中的 $text。
The following query performs a text search for the term cake and uses the $meta operator in the projection document to include the score assigned to each matching document:
db.articles.find( { $text: { $search: "cake" } }, { score: { $meta: "textScore" } } )
该操作将返回以下带有文本分数的文档:
{ "_id" : 4, "title" : "some cakes", "score" : 1 } { "_id" : 1, "title" : "cakes and ale", "score" : 0.75 } { "_id" : 5, "title" : "two cakes to go", "score" : 0.6666666666666666 } { "_id" : 2, "title" : "more cakes", "score" : 1 }
有关 "textScore" 投影和排序的更多其他示例,请参阅相关性分数示例。
$meta: "indexKey"
注意
{ $meta: "indexKey" } 表达式仅用于调试目的,不适用于应用程序逻辑。MongoDB 返回与查询系统选择的索引关联的值。系统可以在后续执行时选择不同的索引。
对于所选索引,返回的值取决于数据库决定如何表示索引中的值,并且可能会因版本而异。所表示的值可能不是该字段的实际值。
使用以下文档创建 orders 集合:
db.orders.insertMany([ { "item" : "abc", "price" : Decimal128("12"), "quantity" : 2, "type": "apparel" }, { "item" : "jkl", "price" : Decimal128("20"), "quantity" : 1, "type": "electronics" }, { "item" : "abc", "price" : Decimal128("10"), "quantity" : 5, "type": "apparel" } ])
在 type 和 item 字段上创建以下复合索引:
db.orders.createIndex( { type: 1, item: 1 } )
以下聚合操作将查找 type 等于 apparel 的所有文档,并通过 $meta 操作符加入匹配文档的索引键值(如果使用了索引的话):
db.orders.aggregate( [ { $match: { type: "apparel" } }, { $addFields: { idxKey: { $meta: "indexKey" } } } ] )
The following operation finds all documents with type equal to apparel and uses the $meta operator to include the index key value for the matching document if an index was used:
db.orders.find( { type: "apparel" }, { idxKey: { $meta: "indexKey" } } )
该操作会返回匹配的文档及其相应的索引键:
{ "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dcde"), "item" : "abc", "price" : Decimal128("12"), "quantity" : 2, "type" : "apparel", "idxKey" : { "type" : "apparel", "item" : "abc" } } { "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dce0"), "item" : "abc", "price" : Decimal128("10"), "quantity" : 5, "type" : "apparel", "idxKey" : { "type" : "apparel", "item" : "abc" } }
如果没有使用索引,{ $meta: "indexKey" } 不会返回任何内容。
例如,以下操作不使用索引,因为 price 字段上不存在支持匹配条件的索引:
db.orders.aggregate( [ { $match: { price: { $gte: Decimal128("10") } } }, { $addFields: { idxKey: { $meta: "indexKey" } } } ] )
例如,以下操作不使用索引,因为 price 字段上不存在支持匹配条件的索引:
db.orders.find( { price: { $gte: Decimal128("10") } }, { idxKey: { $meta: "indexKey" } } )
此操作将返回不含 idxKey 字段的匹配文档:
{ "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dcde"), "item" : "abc", "price" : NumberDecimal("12"), "quantity" : 2, "type" : "apparel" } { "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dcdf"), "item" : "jkl", "price" : NumberDecimal("20"), "quantity" : 1, "type" : "electronics" } { "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dce0"), "item" : "abc", "price" : NumberDecimal("10"), "quantity" : 5, "type" : "apparel" }
本页上的C#示例使用Atlas示例数据集中的 sample_mflix数据库。要学习;了解如何创建免费的MongoDB Atlas 群集并加载示例数据集,请参阅MongoDB .NET/ C#驱动程序文档中的入门。
以下 Movie 类对 sample_mflix.movies 集合中的文档进行建模:
public class Movie { public ObjectId Id { get; set; } public string Plot { get; set; } public List<string> Genres { get; set; } public int Runtime { get; set; } public List<string> Cast { get; set; } public string Title { get; set; } [] public DateTime LastUpdated { get; set; } public string Rated { get; set; } public int Year { get; set; } public ImdbData Imdb { get; set; } public string Type { get; set; } public int Index { get; set; } public string[] Comments { get; set; } public List<BsonDocument> Highlights { get; set; } public float Score { get; set; } [] public SearchScoreDetails ScoreDetails { get; set; } [] public SearchScoreDetails SearchScoreDetails { get; set; } [] public string PaginationToken { get; set; } [] public float[] PlotEmbedding { get; set; } }
注意
用于 Pascal Case 的 ConventionPack
此页面上的 C# 类在其属性名称中使用 Pascal 命名法,而 MongoDB 集合中的字段名称则使用 camel 命名法。为了解决这种差异,可以在应用程序启动时使用以下代码注册一个 ConventionPack:
var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() }; ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);
要使用 .NET/C# 驱动程序包含文本搜索分数,请在投影构建器上调用 MetaTextScore() 方法。
首先,运行以下代码,以在 Title 字段上创建文本索引:
var indexModel = new CreateIndexModel<Movie>( Builders<Movie>.IndexKeys.Text(m => m.Title)); movieCollection.Indexes.CreateOne(indexModel);
然后,将以下代码添加到您的应用程序中。该代码执行术语 "future" 的文本搜索,并使用 MetaTextScore() 方法将分配给每个匹配文档的得分包括在内。然后,代码按文本分数对结果进行降序排序,并返回得分最高的文档。
var filter = Builders<Movie>.Filter.Text("future"); var projection = Builders<Movie>.Projection .Include(m => m.Title) .Include(m => m.Plot) .MetaTextScore(m => m.Score); var result = movieCollection.Find(filter) .Sort(Builders<Movie>.Sort.MetaTextScore("score")) .Project(projection) .FirstOrDefault();
之前的操作将返回以下文档:
{ "_id": { "$oid": "573a1398f29313caabceb500" }, "plot": "After visiting 2015, Marty McFly must repeat his visit to 1955 to prevent disastrous changes to 1985... without interfering with his first trip.", "title": "Back to the Future Part II", "score": 1.59375 }