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以适应您的需求。