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

Spring data - Count distinct items from grouping

我有访问用户的数据库,其中包含 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"
            }
        }
    }])

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

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

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

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

感谢任何帮助。

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

$addToSet operator will create a "unique" array ( or "set" ) of the elements you ask to add to it. It is however basically another form of $group 本身,不同之处在于元素被添加到结果中的 "array"(或 "set")。

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

因此,由于$group实际上是一回事,您还需要"two"个流水线阶段来获得"distinct"个计数,然后只需"two"$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 }
    }}
]

这是一个简单的代码,它比 "scalable" 多得多,因为各个 "user_id" 值最初包含在管道中的单独文档中。因此 "second" $group(代替带有 $size 的 $project)"counts" 已经在第一个分组键中确定的不同金额。

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