首先,我的数据库中有两个可能的文档的例子
{
"_id" : "0"
"data": {
"lettersCollection" : [
{"lettersList" : ["A","B","C"] },
{"lettersList" : ["D","T","E"] },
{"lettersList" : ["X","Y","Z"] },
]
}
}
{
"_id" : "1"
"data": {
"lettersCollection" : [
{"lettersList" : ["A","B","D"] },
{"lettersList" : ["X","Y","Z"] },
{"lettersList" : ["E","C","M"] },
]
}
}
我想要完成什么?
我想列出一个字母及其出现次数的下降列表。
例如:如果数据库仅包含上述2个文档,则结果为:
A - 2
B - 2
C - 2
D - 2
E - 2
X - 2
Y - 2
Z - 2
T - 1
M - 1
注意:一封信只能在文档中出现一次。例如,字母“B”不可能在特定文档的任何lettersList中出现多次
到目前为止我尝试了什么?
我是MongoDB的新手,我越接近这个查询,它只适用于单个值(例如:_id,它始终是唯一的,因此计数总是1),并且不会迭代嵌套数组,不按降序排列:
db.test.group({
"key": {
"_id": true
},
"initial": {
"countstar": 0
},
"reduce": function(obj, prev) {
if (true != null) if (true instanceof Array) prev.countstar += true.length;
else prev.countstar++;
}
});
答案 0 :(得分:3)
您可以使用aggregation pipeline(通常应该是您的首选聚合)来执行此操作:
db.test.aggregate([
// Duplicate the docs, once per lettersCollection element
{$unwind: '$data.lettersCollection'},
// Duplicate the docs again, this time once per lettersList
{$unwind: '$data.lettersCollection.lettersList'},
// Group them back together by letter and count them
{$group: {_id: '$data.lettersCollection.lettersList', count: {$sum: 1}}},
// Sort by count descending
{$sort: {count: -1}}
])
输出:
{
"result" : [
{
"_id" : "Z",
"count" : 2
},
{
"_id" : "X",
"count" : 2
},
{
"_id" : "Y",
"count" : 2
},
{
"_id" : "E",
"count" : 2
},
{
"_id" : "D",
"count" : 2
},
{
"_id" : "C",
"count" : 2
},
{
"_id" : "B",
"count" : 2
},
{
"_id" : "A",
"count" : 2
},
{
"_id" : "M",
"count" : 1
},
{
"_id" : "T",
"count" : 1
}
],
"ok" : 1
}