Java Spring数据-从分组中计数不同的项
我有访问用户到地点的数据库,其中包含地点id和用户id,如下所示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
{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
。但双$组
的效率要高得多。在需要的地方,我有来自“定制”管道阶段的代码,所以您最初的想法是可能的。但无论如何,这真的更好。所以我才这样回答。