对存储在两个单独字段中的ObjectID的出现次数进行分组和计数

时间:2016-07-26 11:59:04

标签: mongodb mongoose mongodb-query aggregation-framework

我是MongoDB的新手,我不知道如何以有效的方式解决这个问题。 在我的应用程序中,用户可以在一个或另一个对象之间进行选择(多次,通过给出正/负评级)。我想要做的是计算一个物体被评为正面和负面的次数。 为了给你一个更精确的想法,这里有一些数据样本(我删除了一些字段以使其更简单)(我需要这种形式的数据,因为不允许用户对同一对对象进行两次评分):

{
    "_id" : ObjectId("579688a5336f04d208747fe8"),
    "positive" : ObjectId("5796708d58cc25ab040a6cda"),
    "negative" : ObjectId("5796705c58cc25ab040a6cd7")
},
{
    "_id" : ObjectId("579688a7336f04d208747fe9"),
    "positive" : ObjectId("5796706358cc25ab040a6cd8"),
    "negative" : ObjectId("5796708058cc25ab040a6cd9")
},
{
    "_id" : ObjectId("579688a8336f04d208747fea"),
    "positive" : ObjectId("5796708d58cc25ab040a6cda"),
    "negative" : ObjectId("5796706358cc25ab040a6cd8")
},
{
    "_id" : ObjectId("579688a8336f04d208747feb"),
    "positive" : ObjectId("5796708d58cc25ab040a6cda"),
    "negative" : ObjectId("5796706358cc25ab040a6cd8")
}...

我需要运行一个以这种方式返回数据的命令:

{
  "_id": ObjectId("5796708d58cc25ab040a6cda"),
  "positiveCount": 3,
  "negativeCount": 0
},
{
  "_id": ObjectId("5796705c58cc25ab040a6cd7"),
  "positiveCount": 0,
  "negativeCount": 1
}, ...

到目前为止,我只能使用此命令分别计算正或负评级的数量:

db.getCollection('votes').aggregate([
{$group:{_id:'$positive', count: {$sum:1}}}
]);

这可行,但只计算正面或负面投票。这是我得到的结果

{
    "_id" : ObjectId("57971bb60711a9a6046dccc7"),
    "count" : 7.0
},
{
    "_id" : ObjectId("5796708058cc25ab040a6cd9"),
    "count" : 21.0
}...

到目前为止,我的解决方案是运行查询两次(一个用于正面,一个用于负面评级),然后在应用级别合并它们。我问你是否有更好,更高效的方法来实现这个结果。 谢谢你的建议。

1 个答案:

答案 0 :(得分:0)

我建议你使用mapReduce函数。这是一个可能的解决方案:

var map = function() {
    if (this.positive) {
        emit(this.positive, { positiveCount: 1, negativeCount: 0 });
    }
    if (this.negative) {
        emit(this.negative, { positiveCount: 0, negativeCount: 1 });
    }
};

var reduce = function (key, values) {
     var o = { positiveCount: 0, negativeCount: 0 };
     for (var i = 0; i < values.length; i++) {
         if (values[i].positiveCount === 1) {
             o.positiveCount++;
         }
         if (values[i].negativeCount === -1) {
             o.negativeCount++;
         }
     }
     return o;
};

db.pairs.mapReduce(map, reduce, { out: "solution" } );

现在,你的总数是正数/负数。查询solution集合,您可以看到结果。