Mongodb 按聚合中字段的最常出现值分组
假设我有两个字段Mongodb 按聚合中字段的最常出现值分组,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,假设我有两个字段A和B。字段A可以采用以下值:[A,b,c,d,e]和b:[x,y] 我正在寻找一个MongoDB聚合管道查询,它将: 计算A的每个值在我的数据库中出现的次数 显示AA最常出现的值的B值的分布 示例: 假设‘c’恰好是A的最常出现的值: 产出将是: { '_id': { 'A': 'c', 'B': 'x' }, 'count': 43 } { '_id': { 'A': 'c', 'B': 'y' }, 'count': 13 } 我做到这一点的唯一方法是将A:c硬编码到我的
A
和B
。字段A
可以采用以下值:[A,b,c,d,e]
和b:[x,y]
我正在寻找一个MongoDB聚合管道查询,它将:
A
的每个值在我的数据库中出现的次数A
A最常出现的值的B
值的分布{ '_id': { 'A': 'c', 'B': 'x' }, 'count': 43 }
{ '_id': { 'A': 'c', 'B': 'y' }, 'count': 13 }
我做到这一点的唯一方法是将
A:c
硬编码到我的“$match”
语句中 您可以从输出推断聚合管道。\u id
字段有两个键A
和B
,这两个键推断键由两个键组成,通过调用累加器获取计数
填充测试集合
假设我们使用以下文档生成一个测试集合
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
}
/* 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
}
根据观察,计数为11的文档#2的最常出现值为“c”:
/* 2 */
{
"_id" : {
"A" : "c",
"B" : "x"
},
"count" : 11
}
至此,您可以进一步聚合以获得计数最多的密钥。您需要另一个管道,该管道将通过
键对上一管道的结果进行分组,创建一个包含文档详细信息的列表,即。
计数以及相应的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" : {
"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
}
/* 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 }
])
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.显示A最常出现值的B
值的分布