我们说我有2个字段A
和B
。字段A
可以采用以下值:[a,b,c,d,e]
和B:[x,y]
。
我正在寻找一个MongoDB聚合管道查询:
A
中每个值出现在我的数据库中的次数B
A
的值的分布
醇>
示例:
让我们说' c'恰好是A的最大值:
输出结果为:
{ '_id': { 'A': 'c', 'B': 'x' }, 'count': 43 }
{ '_id': { 'A': 'c', 'B': 'y' }, 'count': 13 }
我设法做到这一点的唯一方法是将A:c
硬编码到我的"$match"
语句中。
答案 0 :(得分:1)
您可以从输出中推断出聚合管道。 _id
字段有两个键A
和B
,表示 $group
键由两个键组成,并且计数是通过调用 $sum
累加器。
填充测试集
假设我们使用以下文档生成测试集合
db.collection.insert([
{ "A": "c", "B": "x" },
{ "A": "c", "B": "x" },
{ "A": "c", "B": "x" },
{ "A": "e", "B": "x" },
{ "A": "c", "B": "x" },
{ "A": "c", "B": "x" },
{ "A": "a", "B": "x" },
{ "A": "c", "B": "x" },
{ "A": "c", "B": "x" },
{ "A": "a", "B": "x" },
{ "A": "c", "B": "y" },
{ "A": "c", "B": "x" },
{ "A": "c", "B": "x" },
{ "A": "b", "B": "x" },
{ "A": "c", "B": "x" },
{ "A": "c", "B": "x" },
{ "A": "a", "B": "y" },
{ "A": "a", "B": "y" },
{ "A": "b", "B": "y" },
{ "A": "b", "B": "y" },
{ "A": "b", "B": "y" },
{ "A": "b", "B": "y" },
{ "A": "b", "B": "y" },
{ "A": "c", "B": "y" },
{ "A": "e", "B": "y" },
{ "A": "e", "B": "y" },
{ "A": "d", "B": "y" },
{ "A": "d", "B": "y" },
{ "A": "d", "B": "y" }
])
然后,以下初始管道将对这两个键上的文档进行分组并获取计数:
db.collection.aggregate([
{
"$group": {
"_id": { "A": "$A", "B": "$B" },
"count": { "$sum": 1 }
}
}
])
示例输出
/* 1 */
{
"_id" : {
"A" : "e",
"B" : "y"
},
"count" : 2
}
/* 2 */
{
"_id" : {
"A" : "c",
"B" : "x"
},
"count" : 11
}
/* 3 */
{
"_id" : {
"A" : "b",
"B" : "y"
},
"count" : 5
}
/* 4 */
{
"_id" : {
"A" : "b",
"B" : "x"
},
"count" : 1
}
/* 5 */
{
"_id" : {
"A" : "e",
"B" : "x"
},
"count" : 1
}
/* 6 */
{
"_id" : {
"A" : "d",
"B" : "y"
},
"count" : 3
}
/* 7 */
{
"_id" : {
"A" : "a",
"B" : "y"
},
"count" : 2
}
/* 8 */
{
"_id" : {
"A" : "a",
"B" : "x"
},
"count" : 2
}
/* 9 */
{
"_id" : {
"A" : "c",
"B" : "y"
},
"count" : 2
}
从观察来看,具有计数11的文档#2具有" c"作为最有价值的值:
/* 2 */
{
"_id" : {
"A" : "c",
"B" : "x"
},
"count" : 11
}
到目前为止,您可以进一步聚合以获得最重要的密钥。您需要另一个 $group
管道,它将通过A
键对上一个管道的结果进行分组,创建一个包含文档详细信息的列表,即
计数和具有该计数的相应B
值。您还需要每组A
值的计数字段:
db.collection.aggregate([
{
"$group": {
"_id": { "A": "$A", "B": "$B" },
"count": { "$sum": 1 }
}
},
{
"$group": {
"_id": "$_id.A",
"counts": {
"$push": {
"B": "$_id.B",
"count": "$count"
}
},
"count": { "$sum": "$count" }
}
}
])
示例输出
/* 1 */
{
"_id" : "e",
"counts" : [
{
"B" : "y",
"count" : 2
},
{
"B" : "x",
"count" : 1
}
],
"count" : 3
}
/* 2 */
{
"_id" : "c",
"counts" : [
{
"B" : "x",
"count" : 11
},
{
"B" : "y",
"count" : 2
}
],
"count" : 13
}
/* 3 */
{
"_id" : "b",
"counts" : [
{
"B" : "y",
"count" : 5
},
{
"B" : "x",
"count" : 1
}
],
"count" : 6
}
/* 4 */
{
"_id" : "d",
"counts" : [
{
"B" : "y",
"count" : 3
}
],
"count" : 3
}
/* 5 */
{
"_id" : "a",
"counts" : [
{
"B" : "y",
"count" : 2
},
{
"B" : "x",
"count" : 2
}
],
"count" : 4
}
在此阶段,您只需要对计数字段中的文档进行排序,并在按降序排列文档时返回顶部文档:
db.collection.aggregate([
{
"$group": {
"_id": { "A": "$A", "B": "$B" },
"count": { "$sum": 1 }
}
},
{
"$group": {
"_id": "$_id.A",
"counts": {
"$push": {
"B": "$_id.B",
"count": "$count"
}
},
"count": { "$sum": "$count" }
}
},
{ "$sort": { "count": -1 } },
{ "$limit": 1 }
])
产生:
{
"_id" : "c",
"counts" : [
{
"B" : "x",
"count" : 11
},
{
"B" : "y",
"count" : 2
}
],
"count": 13
}
虽然输出与所需的结构不同,但仍能充分解决问题
1。计算A
中每个值出现在我的数据库中的次数 - >所需的管道:
db.collection.aggregate([
{
"$group": {
"_id": { "A": "$A", "B": "$B" },
"count": { "$sum": 1 }
}
},
{
"$group": {
"_id": "$_id.A",
"count": { "$sum": "$count" }
}
}
])
2。显示B
的最新值A的分布
db.collection.aggregate([
{
"$group": {
"_id": { "A": "$A", "B": "$B" },
"count": { "$sum": 1 }
}
},
{
"$group": {
"_id": "$_id.A",
"counts": {
"$push": {
"B": "$_id.B",
"count": "$count"
}
},
"count": { "$sum": "$count" }
}
},
{ "$sort": { "count": -1 } },
{ "$limit": 1 }
])