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

Java Spring数据-从分组中计数不同的项,java,mongodb,mongodb-query,aggregation-framework,spring-mongodb,Java,Mongodb,Mongodb Query,Aggregation Framework,Spring Mongodb,我有访问用户到地点的数据库,其中包含地点id和用户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和用户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( ???);

非常感谢您的帮助。

我将在“一次成功”中回答这一问题,因此,与其解决您的“$project”问题,不如在此建议有更好的方法

操作员将为您请求添加到其中的元素创建一个“唯一”数组(或“集合”)。然而,它本身基本上是另一种形式的,不同之处在于元素被添加到结果中的“数组”(或“集合”)

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

因此,由于
$group
实际上是同一件事,而且您还需要“两个”管道阶段来获得“不同”计数,然后只需要“两个”
$group
阶段:

    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 }
    }}
]
这是一段简单的代码,它更具“可伸缩性”,因为单个的“user_id”值最初包含在管道中的单独文档中。因此,“第二个”
$group
(代替$size的$project)“计算”第一个分组键中已经确定的不同金额


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

我考虑了两个管道阶段,但我不够聪明,无法创建基于这两个标识符的组合键。谢谢您的回答。@IgorPiddubnyi无论您以何种方式看待它,它仍然是两个管道阶段,即使使用
$project
。但双
$组
的效率要高得多。在需要的地方,我有来自“定制”管道阶段的代码,所以您最初的想法是可能的。但无论如何,这真的更好。所以我才这样回答。