所以我有这个疑问,
db.collection.find({$where: "this.field1 !== this.field2"})
但现在我需要创建一个类似的查询并将结果聚合到一个复杂的查询中,该查询经过尝试并且是正确的,只能通过使用聚合管道或“大炮苍蝇”并使用mapReduce选项来完成。
既然我想避免mapReduce,有没有办法实现类似于{$where: "this.field1 !== this.field2"}
的东西方法?
一些观察,解决上述情况的一般方法的答案是最理想的,但如果不可能,为了解决我的问题,我也可以使用原始值在具有以下限制的查询中。我需要找到以下内容
db.collection.find({ $or :[
{field1: value},
{field2: value}
], $and: [
{ field1: {$not: {$eq: value}}},
{ field2: {$not: {$eq: value}} }
]})
我尝试了上面的查询,但它丢弃了包含任一字段中的值的结果,而我想要的是一种方法来丢弃同时在两个字段中具有相同值的对象 ,但是获取在任一字段中具有值的文档,我通常更喜欢单查询方法,但在阅读了大量内容后,我认为避免使用 mapReduce 的唯一选择是执行类似的操作
db.collection.find({$where: "this.field1 === this.field2"}, function (err, results){
var match = { $or :[
{field1: value},
{field2: value}
], {
_id : { $not : {$in: results.map((x) => x._id)}}
}
db.collection([ {$match: match}, {$project: projectionObject}, ...., etc])
})
所以我将使用上面的 be 解决方案,它可以优化很多(我只是在写问题时写的),但我想避免将一个非常大的 objectId 列表发送回数据库如果可能的话。我将对其进行一些重构,以在 where 语句之前使用匹配运算符
最佳答案
这是一个复杂的情况,也许你可以在 $project
中使用 $cond
的技巧
var projectDataForMatch = {
$project : {
_id : 1, //list all fields needed here
filterThisDoc : {
$cond : {
if : {
$eq : ["$field1", "$filed2"]
},
then : 1,
else : 0
} //or use compare operator $cmp
}
}
}
var match = {
$match : {
filterThisDoc : 1
}
}
db.col.aggregate([projectDataForMatch, match])
您可以根据需要扩展$cond
以满足您的需求。
关于javascript - Mongo聚合$match相当于{$where : "this.field1 !== this.field2"},我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37530386/