$unwind 可能很昂贵。这不是更容易查询吗?
db.collection =
[
{ name : 'bob', to : 'mary', day : 1, count : 2 },
{ name : 'mary', from : 'bob', day : 1, count : 2 },
{ name : 'bob', to : 'steve', day : 2, count : 1 },
{ name : 'bob', from : 'steve',day : 2, count : 1 },
{ name : 'mary', to : 'bob', day : 1, count : 3 },
{ name : 'mary', from : 'bob', day : 1, count : 3 },
{ name : 'mary', to : 'steve', day : 3, count : 1 },
{ name : 'mary', from : 'steve' day : 3, count : 1 },
{ name : 'steve', to : 'bob', day : 2, count : 2 },
{ name : 'steve', from : 'bob', day : 2, count : 2 },
{ name : 'steve', to : 'mary', day : 1, count : 1 }
{ name : 'steve', from : 'mary', day : 1, count : 1 }
]
[更新]
使用您现有的结构,您可以使用 Map-Reduce 执行此操作,但这并不是真正的实时结果。总体上它会更慢,但可能比 AF 中的大规模 $unwind 操作更有效;
db.so.drop();
db.so.insert(
[
{ from: 'bob', to: 'mary', day: 1, count: 2 },
{ from: 'bob', to: 'steve', day: 2, count: 1 },
{ from: 'mary', to: 'bob', day: 1, count: 3 },
{ from: 'mary', to: 'steve', day: 3, count: 1 },
{ from: 'steve', to: 'bob', day: 2, count: 2 },
{ from: 'steve', to: 'mary', day: 1, count: 1 }
]);
db.runCommand(
{
"mapreduce": "so", // don't need the collection name here if it's above
"map": function(){
emit(this.from, {count: this.count});
emit(this.to, {count: this.count});
},
"reduce": function (name, values) {
var result = { count: 0 };
values.forEach(function (v) {
result.count += v.count;
});
return result;
},
query: {},
out: { inline: 1 },
}
);
产生;
{
"results" : [
{
"_id" : "bob",
"value" : {
"count" : 8
}
},
{
"_id" : "mary",
"value" : {
"count" : 7
}
},
{
"_id" : "steve",
"value" : {
"count" : 5
}
}
],
"timeMillis" : 1,
"counts" : {
"input" : 6,
"emit" : 12,
"reduce" : 3,
"output" : 3
},
"ok" : 1
}