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



我有访问用户的地方,其中包含place_id和user_id像这样的db

{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"
            }
        }
    }])

现在我想使用Spring Data来实现它,现在的问题是投影中的$size操作,因为Spring Data API没有这样的,至少我没有在参考中找到它。

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

也许有任何方法也可以创建大小字段,比嵌套api可以使用:

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

我将以"一击"的方式回答这个问题,而不是解决你的"$project"问题,我在这里建议有一个更好的方法。

$addToSet 操作符将创建一个"唯一"数组(或"集合"),其中包含您要求添加的元素。然而,它本身基本上是 $group 的另一种形式,不同的是元素在结果中被添加到"数组"(或"集合")中。

这对于可伸缩性来说是"坏的",因为这里的潜在问题是"set"实际上超过了文档大小的BSON限制。也许现在还没有,但是谁知道你现在写的代码十年后会做什么呢。

因此,由于$group实际上是相同的事情,并且您还需要"两个"管道阶段来获得"不同"计数,那么只需"两个"$group阶段即可:

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

在shell中相当于:

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

这是一个简单的代码,它更"可扩展",因为单独的"user_id"值首先包含在管道中的单独文档中。因此,"第二个"$group(代替带有$size的$project)"计数"已在第一个分组键中确定的不同数量。

了解局限性和缺陷,并编写好代码。

相关内容

  • 没有找到相关文章

最新更新