2016-07-26 3 views
3

MongoDBが新しく、この問題を効率的に解決する方法がわかりません。 私のアプリでは、ユーザーはあるオブジェクトか別のオブジェクトのどちらかを選択できます(複数回、肯定/否定の評価を与えることによって)。私がしたいのは、オブジェクトがプラスとマイナスに評価された回数を数えることです。 より正確なアイデアを得るために、いくつかのデータサンプルを示します(これを簡単にするためにいくつかのフィールドを削除しました)(このフォームでデータを必要とするのは、ユーザーが同じオブジェクトペアを2回評価することができないためです):2つの別々のフィールドに格納されたObjectIDの出現回数をグループ化してカウントする

{ 
    "_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対1に)クエリを実行し、アプリレベルでそれらをマージすることです。この結果を達成するためのより良い、より良い方法があるかどうか尋ねています。 アドバイスありがとうございます。

答えて

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コレクションを照会すると、結果が表示されます。

+0

お返事ありがとうございます。私はすでにこのソリューションについて考えてきましたが、それは私の要求に合っていません。私は「特定の日付の後に行われたレーティングに対して肯定的/否定的な票を得る」のようなフィルタもいくつか持っているので、クエリを実行する必要があります。ユーザーが特定のオブジェクトのペアに対して2回投票することはできませんが、同じオブジェクトを複数のオブジェクト(異なるオブジェクトに対して)に投票することはできます。もう少し明確になることを願っています。 – user2030337

+0

本当はいいえ。つまり、あなたのニーズにはどんな解決策がありますか?なぜそれが収まりませんか? – Odonno

+0

私の質問では、私は部分的な解決法を掲示しました。これは、文書の正の評価回数を数えるクエリですが、負の評価も必要です(同じ文書の場合)。私はまた、私が必要とする期待される結果を掲示しました。 – user2030337

関連する問題