MongoDB :查询具有两个相等字段的文档,$match 和 $eq



如果我想要 document.a == document.b,返回集合中所有文档的最佳方法是什么?

我试过了

db.collection.aggregate([ { $match: { $eq: [ '$a', '$b' ] } }])

但它返回没有错误或结果,因为我认为它实际上是匹配字符串"$a"和"$b"。 有没有其他方法可以指定这些是字段?

db.collection.aggregate([    { $project: { 
    eq: { $cond: [ { $eq: [ '$a', '$b' ] }, 1, 0 ] } 
} },
{ $match: { eq: 1 } }])

上述方法有效,但需要额外的步骤,即再次查询找到的任何文档或投影所有可能的字段。

有没有更好的方法来实现此查询?

如果我

理解正确您的问题,您需要那些在字段 1 和字段 2 中具有相同值的文档。

为此尝试

db.coll.find({$where: function() { return this.field1 == this.field2 } } );

或更紧凑

db.coll.find({ $where : "this.field1 == this.field2" } );

基本上,您正在尝试执行自加入。MongoDB 不支持的操作。

关于$eq运算符,正如您所猜测的:

  • 根据设计,$eq比较查询运算符将字段与进行匹配。
  • 但是$eq比较聚合运算符比较两个表达式的值。

我不知道除了使用您建议的额外$project步骤之外,任何其他方法来执行您需要的操作。

请注意,这并没有明显增加,因为无论如何,您的查询不能使用任何索引,MongoDB将进行完全扫描。

我正在使用 AWS DocumentDb,不支持$expr(截至 2023 年 5 月 16 日)。 我使用 NatNgs 的建议使用 $addFields 来比较同一文档中的两个字段:

db.collection.aggregate($addFields: {
  "matchedValue" : {
    $cond: {
      if: {
        "$eq" : [ "$a", "$b" ]
      },
      then: "$a",
      else: false
    }
  }
});

这会matchedValue字段添加到文档中,但现在我们有一个可以过滤的值。

我又使用了一个$match阶段来过滤掉false值。