代码之家  ›  专栏  ›  技术社区  ›  Igor Piddubnyi

Spring数据-统计分组中的不同项

  •  1
  • Igor Piddubnyi  · 技术社区  · 10 年前

    我有访问用户的数据库,其中包含place_id和user_id,如下所示

    {place_id : 1, user_id : 1}
    {place_id : 1, user_id : 1}
    {place_id : 1, user_id : 2}
    {place_id : 2, user_id : 3}
    {place_id : 2, user_id : 3}
    

    我希望每个地方都有大量不同的用户。我最终得到了以下原生mongo聚合:

    db.collection.aggregate([{
            $group: {
                _id: "$place_id",
                setOfUsers: {
                    $addToSet: "$user_id"
                }
            }
        }, {
            $project: {
                distinctUserCount: {
                    $size: "$setOfUsers"
                }
            }
        }])
    

    现在我想用SpringData实现它,现在的问题是投影中的$size操作,因为Spring数据API没有这样的操作,至少我在引用中没有找到它。

        GroupOperation group = Aggregation.group("place_id").addToSet("user_id").as("setOfUsers");
        ProjectionOperation project = Aggregation.project(). .... ?
    

    也许还有任何方法可以创建大小字段,而不是使用嵌套的api:

    Aggregation.project().and("distinctUserCount").nested( ???);
    

    感谢任何帮助。

    1 回复  |  直到 10 年前
        1
  •  3
  •   Blakes Seven    10 年前

    我将在“一击”中回答这个问题,因此我将在这里建议有更好的方法,而不是解决您的“$project”问题。

    这个 $addToSet 运算符将创建一个“唯一”数组(或“集合”),其中包含要添加到其中的元素。然而,这基本上是另一种形式的 $group 就其本身而言,不同之处在于元素被添加到结果中的“数组”(或“集合”)中。

    这对于可扩展性来说是“糟糕的”,因为这里的潜在问题是“集合”实际上超过了文档大小的BSON限制。也许现在还没有,但谁知道你现在写的代码十年后会做什么。

    因此,自 $组 实际上是一样的,您还需要“两个”管道阶段来获得“不同的”计数,然后只需要“两” $组 阶段:

        Aggregation pipeline = newAggregation(
            group(fields("place_id","user_id")),
            group("_id.place_id").count().as("distinctUserCount")
        );
    

    外壳等效于:

    [
        { "$group": {
            "_id": { "place_id": "$place_id", "user_id": "$user_id" }
        }},
        { "$group": {
            "_id": "$_id.place_id",
            "distinctUserCount": { "$sum": 1 }
        }}
    ]
    

    这是一个简单的代码,而且它更“可扩展”,因为individualt“user_id”值最初包含在管道中的单独文档中。因此,“第二” $组 (代替$size的$project)“计算”第一个分组键中已确定的不同金额。

    了解限制和陷阱,并编写好代码。