如果我收集了一些文件,其格式为:
{
"_id" : ObjectId("53202e1d78166396592cf805"),
"a" : 4,
"b" : 2,
"c" : 4,
"d" : 3
}
如何选择具有以下条件的文件:
db.stat.find({' a' +''>' c' +' d'})
可能,使用聚合,但接下来是什么条件" macth":
db.stat.aggregate([
{$project : {
_id : '$_id',
'ab' : { '$add' : [ '$a', '$b' ] },
'cd' : { '$add' : [ '$c', '$d' ] }
}},
{$match: {???}}
]);
感兴趣的是没有mapReduce的解决方案,也没有人工方法将值与零($subtract:["$ab", "$cd"] > 0
)进行比较。
答案 0 :(得分:3)
那么在$ match之前还有一步:
db.stat.aggregate([
{ "$project" : {
"ab": { "$add" : [ "$a", "$b" ] },
"cd": { '$add' : [ "$c", "$d" ] }
}},
{ "$project": {
"matched": {"$gt": [ "$ab", "$cd" ] }
}},
{ "$match": { "matched": true } }
])
甚至更好:
db.stat.aggregate([
{ "$project": {
"matched": { "$gt": [
{ "$add" : [ "$a", "$b" ] },
{ "$add" : [ "$c", "$d" ] }
]}
}},
{ "$match": { "matched": true } }
])
概述保留原始文档see here。
当然总有这个,好吧"不漂亮"形式:
db.stats.find(function() {
return ( ( this.a + this.b ) > (this.c + this.d) );
})
但这是$where运算符表单的快捷方式,它将删除您使用索引进行选择的能力。
所以希望你可以通过初始$ match来选择你想要测试的文档,因此聚合方式更好,因为初始$ match可以使用索引。