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
    值的分布
  • 示例:

    假设‘c’恰好是A的最常出现的值:

    产出将是:

    { '_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
    值的分布