MongoDB聚合运算符:$meta

本文详细介绍了MongoDB中元数据运算符$meta的应用,特别是在聚合、查找和投影中使用textScore(文本分数)以及indexKey(索引键)的功能,展示了如何利用这些元数据进行文本搜索、排序和调试索引选择。

$meta聚合运算符用于返回文档相关的元数据,例如执行文本搜索时的“textScore”。

语法

{
   
    $meta: <metaDataKeyword> }

$meta表达式可以为<metaDataKeyword>指定下面的值:

  • “textScore”:返回$text查询时每个匹配文档的分数,文本分数表示文档与搜索词的匹配程度。{$meta: "textScore}必须要与$text查询结合使用。在较早前的版本,如果不与$text联合使用,返回null的分数。
  • “indexKey”:当使用非文本索引时,返回一个文档索引键值,{ $meta: "indexKey" }只用于调试,不面向应用逻辑,并且优先于cursor.returnKey()

使用

文本分数元数据 $meta:“textScore”

依赖$text查找
  • {$meta: "textScore"}表达式必须与$text查找联合使用,例如:
    • 在聚合管道中,必须在使用带有$text查询的$match阶段,以便在后续阶段中使用{$meta: "textScore"}表达式,否则操作会报错。
    • 在查找时,必须在查询谓词中指定$text运算符才能使用{ $meta: "textScore" }。如果在查询谓词中未指定 $text 运算符,则操作将失败。
可用性
  • 在聚合中{ $meta: "textScore" }表达式可以包含在接受聚合表达式的各个阶段,如:$project$group$sort等。
  • 在查找时,{ $meta: "textScore" }可以包干在$projectionsort()
在投影中使用
  • { $meta: “textScore” } 表达式可以是投影文档的一部分,以包含文本分数元数据。
  • $meta表达式既可以出现在包含或排除的投影中。
  • 如果将表达式设置为文档中已存在的字段名称,则投影的元数据值将覆盖现有值。
文本分数的筛选
  • 聚合时,在输出文本分值字段的阶段之后,可以在后续阶段指定查询条件或对该字段进行操作。
  • 在查找时,不能对文本分数指定查询条件,需要改用聚合。
在排序中使用
  • { $meta: "textScore" }表达式可以用于排序操作的一部分,按文本分数元数据进行排序。
  • "textScore"元数据按降序排序。
  • 要在排序操作中使用,需要将{ $meta: "textScore" }表达式设置为任意字段名称。查询系统会忽略字段名称。
非投影中的排序
  • 在聚合过程中,可以根据{ $meta: "textScore" }对生成的文档进行排序,而不必同时投影textScore
  • 在查找中,可以根据{ $meta: "textScore" }对结果文档进行排序,而无需同时投影textScore
  • 在MongoDB 4.2及更早版本中,要使用{ $meta: "textScore" }表达式,就必须与sort()一起用于查找操作,还必须在投影中包含相同的表达式。
投影中的排序
  • 在聚合时,如果包含{ $meta: "textScore" }表达式,则投影和排序的表达式可以有不同的字段名,查询系统会忽略排序中的字段名。
  • 在查找中,如果包含{ $meta: "textScore" }表达式,则投影和排序的表达式可以有不同的字段名,查询系统忽略排序中的字段名。
  • 在 MongoDB 4.2 及更早版本中,要包含{ $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集合并给title字段创建一个文本索引:

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" }
])
db.articles.createIndex( {
   
    title: "text"} )
聚合

下面的聚合操作会执行文本搜索,并使用$meta操作符对文本搜索得分进行分组:

db.articles.aggregate(
   [
     {
   
    $match: {
   
    
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

原子星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值