文档菜单
文档首页
/
MongoDB 手册
/ / /

元数据

在本页

  • 定义
  • 行为
  • 示例
$meta

返回与文档关联的元数据,例如在执行文本搜索时返回 "textScore"

A$meta 表达式具有以下语法

{ $meta: <metaDataKeyword> }

$meta 表达式可以指定以下值作为 <metaDataKeyword>

关键字
描述
"textScore"

返回与每个匹配文档对应的$text 查询的分数。文本分数表示文档与搜索词或词组的匹配程度。

必须与 $text 查询一起使用 { $meta: "textScore" }

在早期版本中,如果不与 $text 查询一起使用,则返回的分数为null.

$text 为自托管(非Atlas)部署提供文本查询功能。对于托管在MongoDB Atlas上的数据,MongoDB 提供了改进的全文查询解决方案,Atlas Search。

"indexKey"
如果使用非文本索引,则返回文档的索引键。{ $meta: "indexKey" } 表达式仅用于调试目的,不用于应用程序逻辑,并且比 cursor.returnKey() 更受青睐。

MongoDB Atlas Search 提供了额外的 $meta 关键字,例如

有关详细信息,请参阅 Atlas Search 文档。

重要

以下 $meta 关键字在 稳定 API V1 中不受支持

  • "textScore"

  • "indexKey"

  • "searchScore"

  • "searchHighlights"

  • 表达式 { $meta: "textScore" } 必须与 $text 一起使用。例如

    • 在聚合操作中,您必须在管道中指定一个带有 $match 阶段的 $text 查询,以便在后续阶段中使用 { $meta: "textScore" } 表达式。如果您未在 $match 阶段指定 $text 查询,则操作将失败。

    • 在查找操作中,您必须在查询谓词中指定 $text 操作符以使用 { $meta: "textScore" }。如果您未在查询谓词中指定 $text 操作符,则操作将失败。

    注意

    $text 为自托管(非Atlas)部署提供文本查询功能。对于托管在MongoDB Atlas上的数据,MongoDB 提供了改进的全文查询解决方案,Atlas Search。

  • 在聚合中,{ $meta: "textScore" } 表达式可以包含在各种接受聚合表达式的阶段中,例如 $project$group$sort 等。

  • 在查找中,{ $meta: "textScore" } 表达式可以包含在 投影sort() 中。

  • { $meta: "textScore" } 表达式可以是包含文本得分元数据的 投影 文档的一部分。

  • $meta 表达式可以存在于包含或排除投影中。

  • 如果您将表达式设置为文档中已经存在的字段名,则投影的元数据值将覆盖现有值。

  • 在聚合阶段,在输出包含文本得分字段的阶段之后,您可以在后续阶段指定查询条件或对字段进行操作。例如,请参阅在自托管部署的聚合管道中使用 $text。

  • 在查找操作中,不能对文本得分指定查询条件。请使用聚合操作。

  • 表达式 { $meta: "textScore" } 可以作为排序操作的一部分,按文本得分元数据排序;即

    • 在聚合中,$sort 阶段。

    • 在查找中,sort() 方法。

  • “textScore” 元数据按降序排序。

  • 要在排序操作中使用,将表达式 { $meta: "textScore" } 设置为任意字段名。字段名将被查询系统忽略。

  • 在聚合中,您可以按照{ $meta: "textScore" }对结果文档进行排序,而无需同时投影textScore

  • 在查找中,您可以按照{ $meta: "textScore" }对结果文档进行排序,而无需同时投影textScore

  • 在聚合中,如果您同时在投影和排序中包含{ $meta: "textScore" }表达式,则投影和排序可以为表达式使用不同的字段名。排序中的字段名被查询系统忽略。

  • 在查找中,如果您同时在投影和排序中包含{ $meta: "textScore" }表达式,则投影和排序可以为表达式使用不同的字段名。排序中的字段名被查询系统忽略。

  • 表达式{ $meta: "indexKey" }仅用于调试目的,而不是用于应用程序逻辑。

  • 表达式{ $meta: "indexKey" }cursor.returnKey()更受欢迎。

  • 在聚合中,表达式 { $meta: "indexKey" } 可以包含在多个接受聚合表达式的阶段中,例如 $project$group$sortByCount 等,但不能是 $sort。然而,使用聚合管道,您可以先在 $project$addFields 等)中投影 { $meta: "indexKey" } 表达式,然后在随后的 $sort 阶段中按该字段排序。

  • 在find中,表达式 { $meta: "indexKey" } 只作为投影文档的一部分可用。

  • 返回的值取决于数据库如何决定在索引中表示值,并且可能在不同版本之间发生变化。表示的值可能不是该字段的实际值。

  • 返回的值取决于系统选择的执行计划。例如,如果有两个可能的索引可以用来回答查询,则“indexKey”元数据值取决于哪个索引被选中。

  • 如果索引是未使用,表达式 { $meta: "indexKey" } 不返回值,字段也不包含在输出中。

创建以下文档的 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 in the Aggregation Pipeline on Self-Managed Deployments.

以下查询执行对术语 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" } 仅用于调试目的,不应用于应用程序逻辑。MongoDB 返回由查询系统选择的索引关联的值。系统可以在后续执行中选择不同的索引。

对于所选索引,返回的值取决于数据库如何决定在索引中表示值,并且可能在不同版本之间发生变化。表示的值可能不是字段的实际值。

创建以下文档的 orders 集合

db.orders.insertMany([
{ "item" : "abc", "price" : NumberDecimal("12"), "quantity" : 2, "type": "apparel" },
{ "item" : "jkl", "price" : NumberDecimal("20"), "quantity" : 1, "type": "electronics" },
{ "item" : "abc", "price" : NumberDecimal("10"), "quantity" : 5, "type": "apparel" }
])

typeitem 字段上创建以下复合索引

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" : NumberDecimal("12"),
"quantity" : 2,
"type" : "apparel",
"idxKey" : { "type" : "apparel", "item" : "abc" }
}
{
"_id" : ObjectId("5e98a33ceaf5e9dcf2b8dce0"),
"item" : "abc",
"price" : NumberDecimal("10"),
"quantity" : 5,
"type" : "apparel",
"idxKey" : { "type" : "apparel", "item" : "abc" }
}

如果没有使用索引, { $meta: "indexKey" } 不返回任何内容。

例如,以下操作没有使用索引,因为没有在 price 字段上创建索引来支持匹配条件

db.orders.aggregate(
[
{ $match: { price: { $gte: NumberDecimal("10") } } },
{ $addFields: { idxKey: { $meta: "indexKey" } } }
]
)

例如,以下操作没有使用索引,因为没有在 price 字段上创建索引来支持匹配条件

db.orders.find(
{ price: { $gte: NumberDecimal("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"
}

返回

合并对象