定义
- $meta
- 返回与文档关联的元数据,例如执行文本搜索时返回 - "textScore"。- $meta表达式的语法如下:- { $meta: <metaDataKeyword> } - $meta表达式可以指定以下值作为- <metaDataKeyword>:Keyword说明- "textScore"- 返回与每份匹配文档相应的 - $text查询关联的得分。文本得分表示文档与搜索词的匹配程度。- { $meta: "textScore" }必须与- $text查询结合使用。- 在早期版本中,如果不与 - $text查询结合使用,返回的分数为空值。- $text为自管理(非 Atlas)部署提供文本查询功能。对于MongoDB上托管的数据, MongoDB还提供改进的全文查询解决方案MongoDB Search。- "indexKey"- 如果使用非文本索引,则返回文档的索引键。 - { $meta: "indexKey" }表达式仅用于调试目的,不用于应用程序逻辑,并且比- cursor.returnKey()更受青睐。- MongoDB Search 提供了额外的 - $meta关键字,例如:- 有关详细信息,请参阅MongoDB搜索文档。 - 重要- Stable API V1 不支持以下 - $meta关键字:- "textScore"
- "indexKey"
- "searchScore"
- "searchHighlights"
- "searchSequenceToken"
- "searchScoreDetails"
- "vectorSearchScore"
 - 您可以使用: - searchScore仅在- $search查询中
- vectorSearchScore仅在- $vectorSearch查询中。
 - 如果您在任何其他查询中使用 - searchScore和- vectorSearchScore, MongoDB会记录警告。
行为
文本分数元数据 $meta: "textScore"
需要 $text 搜索
- { $meta: "textScore" }表达式必须与- $text结合使用。例如:- 聚合时,必须在管道中指定具有 - $text查询的- $match阶段,才能在后续阶段中使用- { $meta: "textScore" }表达式。如果未在- $match阶段指定- $text查询,则操作将失败。
- 在查找中,必须在查询谓词中指定 - $text操作符,才能使用- { $meta: "textScore" }。如果未在查询谓词中指定- $text操作符,则操作失败。
 - 注意- $text为自管理(非 Atlas)部署提供文本查询功能。对于MongoDB上托管的数据, MongoDB还提供改进的全文查询解决方案MongoDB Search。
可用性
投影中的使用
按文本分数筛选
- 聚合时,在输出文本分数值字段的阶段之后,可以在后续阶段指定查询条件或对字段进行操作。例如,请参阅自管理部署中的聚合管道中的 $text。 
- 在查找中,不能对文本得分指定查询条件。请改用聚合。 
排序使用
不使用投影进行排序
- 聚合时,可以按 - { $meta: "textScore" }对结果文档进行排序,而无需投影- textScore。
- 在查找中,您可以按 - { $meta: "textScore" }对结果文档进行排序,而无需投影- textScore。
使用投影进行排序
- 在聚合中,如果投影和排序都包含 - { $meta: "textScore" }表达式,则投影和排序可以为该表达式使用不同的字段名称。被查询系统忽略的排序中的字段名称。
- 在查找中,如果投影和排序都包含 - { $meta: "textScore" }表达式,则投影和排序可以为该表达式使用不同的字段名称。查询系统忽略排序中的字段名称。
索引键元数据 $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"} ) 
以下聚合操作将执行文本搜索并使用 $meta 操作符按文本搜索分数对结果进行分组:
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。
以下查询对术语 cake 执行文本搜索,并在投影文档中使用 $meta 操作符来包含分配给每个匹配文档的分数:
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" } } }    ] ) 
以下操作将查找 type 等于 apparel 的所有文档,如果使用了索引,则将使用 $meta 操作符包含匹配文档的索引键值:
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 }