【问题标题】:MongoDB: Aggregation Group operation over a dynamic key-value pairMongoDB:动态键值对上的聚合组操作
【发布时间】:2019-04-10 07:49:14
【问题描述】:

我有一个简单的文档,其中一个字段作为键值对。我只想在聚合中对这些键执行组操作并添加它们的值。但是这对中的键不是固定的,可以是任何东西。

这是一个示例文档。

{
    _id: 349587843,
    matchPair: {
        3 : 21,
        9 : 4,
        7 : 32
    }
},
{
    _id: 349587478,
    matchPair: {
        7 : 11,
        54 : 32,
        9 : 7,
        2 : 19
    }
}

我想要一个类似下面的结果。

{
    _id : 3,
    count : 21
},
{
    _id : 9,
    count : 11
},
{
    _id : 7,
    count : 43
},
{
    _id : 54,
    count : 32
},
{
    _id : 2,
    count : 19
}

我想到了以下查询并尝试使用$unwindoperation,但它不起作用可能是因为“matchPair”不是一个数组,我不知道为$sumoperation 指定什么。

db.MatchPairs.aggregate([
   { "$unwind" : "$matchPair" },
   { "$group" : {
       _id: "$matchPair",
       count : { $sum : $matchPair }
   } }
]);

我也可以尝试 Map-Reduce,但为此我也需要按名称 emit() 键和值。

我确信有一个简单的解决方案,但我想不通。

【问题讨论】:

  • 如果你的键是动态的,聚合框架是不可能的,所以你必须使用 mapReduce
  • 我明白了。您能告诉我如何在emit() 函数中指定键和值吗?
  • 类似问题的map reduce示例:stackoverflow.com/a/41634637/2965883

标签: mongodb mapreduce aggregation-framework key-value


【解决方案1】:

: 您可以首先使用 $objectToArray 投影和重塑 matchPair 字段

3.4.4 版中的新功能。

{
    $project: {
        matchPair: { $objectToArray: '$matchPair' }
    }
}

这会给

{
    matchPair: [{ k: 3, v: 21 }, { k: 9, v: 4 }, ...] 
}

然后$unwind 基于matchPair

{
    $unwind: '$matchPair'
}

这会给

{
    matchPair: { k: 3, v: 21 }
}

然后$project

{
    $project: {
        _id: '$matchPair.k',
        count: '$matchPair.v'
    }
}

这应该给出你想要的输出。一共是

.aggregate([
    {
        $project: {
            matchPair: { $objectToArray: '$matchPair' }
        }
    },
    { $unwind: '$matchPair' },
    {
        $project: {
            _id: '$matchPair.k',
            count: '$matchPair.v'
       }
    }
])

【讨论】:

    【解决方案2】:

    在 $unwind 的 mongoDb 文档中:

    从输入文档中解构一个数组字段以输出一个 每个元素的文档。

    因此,您必须将架构更改为:

    {
        "_id" : ObjectId("5880b57b039a3c89c1db145a"),
        "matchPair" : [ 
            {
                "_id" : "3",
                "count" : 21
            }, 
            {
                "_id" : "9",
                "count" : 4
            }, 
            {
                "_id" : "7",
                "count" : 32
            }
        ]
    },
    {
        "_id" : ObjectId("5880b58c039a3c89c1db145b"),
        "matchPair" : [ 
            {
                "_id" : "7",
                "count" : 11
            }, 
            {
                "_id" : "54",
                "count" : 32
            }, 
            {
                "_id" : "9",
                "count" : 7
            }, 
            {
                "_id" : "2",
                "count" : 19
            }
        ]
    }
    

    然后做:

    db.MatchPairs.aggregate([
        { $unwind : "$matchPair" }
    ]);
    

    将返回:

    {
        "_id" : ObjectId("5880b57b039a3c89c1db145a"),
        "matchPair" : {
            "_id" : "3",
            "count" : 21
        }
    },
    {
        "_id" : ObjectId("5880b57b039a3c89c1db145a"),
        "matchPair" : {
            "_id" : "9",
            "count" : 4
        }
    },
    {
        "_id" : ObjectId("5880b57b039a3c89c1db145a"),
        "matchPair" : {
            "_id" : "7",
            "count" : 32
        }
    },
    {
        "_id" : ObjectId("5880b58c039a3c89c1db145b"),
        "matchPair" : {
            "_id" : "7",
            "count" : 11
        }
    },
    {
        "_id" : ObjectId("5880b58c039a3c89c1db145b"),
        "matchPair" : {
            "_id" : "54",
            "count" : 32
        }
    },
    {
        "_id" : ObjectId("5880b58c039a3c89c1db145b"),
        "matchPair" : {
            "_id" : "9",
            "count" : 7
        }
    },
    {
        "_id" : ObjectId("5880b58c039a3c89c1db145b"),
        "matchPair" : {
            "_id" : "2",
            "count" : 19
        }
    }
    

    然后你只需要进行分组。

    【讨论】:

      猜你喜欢
      • 2016-07-03
      • 2020-01-04
      • 2021-07-27
      • 2021-11-03
      • 2022-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多