mongodb - `$eq` 运算符是否适用于数组点表示法?

标签 mongodb mongodb-query aggregation-framework

我正在尝试在 $lookup$match 管道阶段内使用 $expr 编写聚合查询。我发现了一些与数组点表示法相关的问题。

想象一个集合relations,其数组字段称为nodes

以下查询可以正常返回正确的结果:

db.relations.find({"nodes.0": { "type" : "User", "id" : UUID("dc20f7c7-bd45-4fc1-9eb4-3604428fa551") }})

但是下面的代码什么也没返回:

db.relations.find({$expr: {$and: [ {$eq: ["$nodes.0", { "type" : "User", "id" : UUID("dc20f7c7-bd45-4fc1-9eb4-3604428fa551") }]}]}})

对我来说,它们似乎实际上是相同的,但我不明白为什么结果不同。 我尝试使用 $arrayElemAt 运算符,它有效,但不幸的是它触发了 COLLSCAN 执行计划,这是不可取的,因为我在 nodes.0 上有一个索引。

我在文档中没有发现关于 $eq 运算符的任何特别之处,他们甚至明确提到这两种表达式形式是等效的。

最佳答案

Does the $eq operator work with array dot notation?

没有。 $nodes.0 $eq aggregation operator 中的表达式不正确,与数组字段一起使用时。

$eq aggregation operator有以下语法:

{ $eq: [ <expression1>, <expression2> ] }

您必须使用$reduce以及$arrayElemAt要访问 $eq 运算符中的字段:

查询1

db.relations.find({
  $expr: {
    $eq: [
      {
        $reduce: {
          input: [
            {
              $arrayElemAt: [
                "$nodes",
                0
              ]
            }
          ],
          initialValue: false,
          in: {
            "$and": [
              {
                $eq: [
                  "$$this.type",
                  "User"
                ]
              },
              {
                $eq: [
                  "$$this.id",
                  UUID("dc20f7c7-bd45-4fc1-9eb4-3604428fa551")
                ]
              }
            ]
          }
        }
      },
      true
    ]
  }
})

Playground

替代方案,使用 $eq 运算符 { <field>: { $eq: <value> } }

查询2

db.relations.find({
  "$and": [
    {
      "nodes.0.type": {
        $eq: "User"
      }
    },
    {
      "nodes.0.id": {
        $eq: UUID("dc20f7c7-bd45-4fc1-9eb4-3604428fa551")
      }
    }
  ]
})

MongoDB Playground

如果要执行 IXSCAN,可以使用Query2。您必须创建以下索引:

db.relations.ensureIndex({"nodes.0.id":1})
db.relations.ensureIndex({"nodes.0.type":1})

关于mongodb - `$eq` 运算符是否适用于数组点表示法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64713634/

相关文章:

javascript - MongoDB:如何避免集合中的名称 double

mongodb - Mongo Go 驱动程序 Count() 方法从 Azure CosmosDB MongoDB Api Count() 获取 "Invalid response from server, value field is not a number"

javascript - ModifiedCount 和 upsertedCount 可以都为 0 吗?

python - 使用 MongoDB 作为持久哈希表

mongodb - 如何根据条件 $push 一个字段?

node.js - 具有异步操作的 Mongoose 游标

mongodb - 给定 ID,查找 dueAt 小于 ID.dueAt 的条目

MongoDB聚合数组文档

java - 使用 Spring Data 在 MongoDB 中求和聚合

mongodb - 聚合、从 2 个集合中查找并提取结果