Mongo聚合$匹配相当于{$ where:“this.field1!== this.field2”}
所以我有这个查询, db.collection.find({$where: "this.field1 !== this.field2"})
但是现在我需要创build一个类似的查询,并将结果集中在一个复杂的查询中,这个查询是真实的,只能通过使用聚合pipe道来完成,或者使用“cannon for a fly”并使用mapReduce选项。
因为我想避免mapReduce,有没有办法实现类似于{$where: "this.field1 !== this.field2"}
方法?
一些观察 ,对于解决上述情况的一般方法的答案是最理想的,但是如果这是不可能的,为了解决我的问题,我还可以在查询中使用原始值,并具有以下限制。 我需要find下面的内容
db.collection.find({ $or :[ {field1: value}, {field2: value} ], $and: [ { field1: {$not: {$eq: value}}}, { field2: {$not: {$eq: value}} } ]})
我试过上面的查询,但它放弃包含任何字段中的值的结果,我想要的是一种方法来放弃同时在两个字段中具有相同的值的对象,但获得具有值无论是字段,我通常更喜欢一个查询的方法,但阅读了很多,我认为唯一的select,以避免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]) })
所以我将使用上面的解决scheme,这个解决scheme可以优化很多(我只是在写问题的时候写的),但是我想避免发送一个令人难以置信的大的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
以适应您的需求。