我做了一些研究,似乎可以使用聚合框架查询(即比较)同一集合中的两个字段。使用$ where运算符也是可能的,但我想避免使用低性能的Javascript解决方案。
这是一个示例文档:
{
"_id" : ObjectId("541ba14d2208236d06ff1e57"),
"a" : "foo",
"d" : {
"e" : "foo"
}
}
{
"_id" : ObjectId("541ba14d2208236d06ff1e58"),
"a" : "foo",
"d" : {
"e" : "bar"
}
}
我想选择'a'!='d.e'的文件。我尝试了以下但没有成功:
db.test.aggregate([{$match: {$ne: ['$a', '$d.e']}}]);
答案 0 :(得分:1)
正如您所说,可以通过在查询中发出$where
条件来使用JavaScript完成查询:
db.test.find(function() { return this.a != this.d.e } )
查询的简写形式。
虽然您可以在聚合框架中执行其他操作,但它不会更改查询的基本性质,因为您无法放置比较两个字段值的查询条件。这就是$match
单独无法做到这一点的原因,因为它遵循相同的规则。
"可以" 做的是$project
另一个与您要强制执行的逻辑条件相匹配的字段值。根据您的实际实施情况,这可能会或可能不会更好:
db.test.aggregate([
{ "$project": {
"a": 1,
"d": 1,
"notEqual": { "$ne": [ "$a", "$d.e" ] }
}},
{ "$match": { "notEqual": true } }
])
除非在整个过程中完成其他一些过滤,否则这可能不会对它有很大的意义。但是使用comparison operator进行一般比较以返回可以过滤的真/假结果。
因此,如果可以,最好的办法是通过文档中存在的字段以类似的方式实现此结果。然后,您有一个基本查询条件来查找该值而不是比较。如果您需要定期进行这类检查,那就是这样。
但对于" ad-hoc"目的,你要么坚持使用JavaScript评估,要么使用"投影"在聚合查询中形成(不能使用$ where子句)以进行字段级别比较。