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" 已经在第一个分组键中确定的不同金额。
了解限制和陷阱,好好编码。
我有访问用户的数据库,其中包含 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" 已经在第一个分组键中确定的不同金额。
了解限制和陷阱,好好编码。