我有访问地点的用户数据库,其中包含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 Data实现它,现在的问题是投影中的$ size操作,因为Spring数据API没有这样的,至少我还没有在参考中找到它。
GroupOperation group = Aggregation.group("place_id").addToSet("user_id").as("setOfUsers");
ProjectionOperation project = Aggregation.project(). .... ?
也许有任何方法可以创建大小字段,而不是使用嵌套的api:
Aggregation.project().and("distinctUserCount").nested( ???);
感谢任何帮助。
答案 0 :(得分:2)
我将在"一次点击"中回答这个问题,而不是解决你的" $项目"问题,我在这里建议有一个更好的方法。
$addToSet
运营商将创建一个"唯一的"要求添加到其中的元素的数组(或" set")。然而,它本质上是$group
的另一种形式,不同之处在于元素被添加到"数组" (或"设置")在结果中。
这是"坏"对于可扩展性,因为你的潜在问题是" set"实际上超过了文件大小的BSON限制。也许它现在不行,但是谁知道你现在编写的代码将在十年内完成。
因此,$group
实际上是相同的,你也需要"两个"管道阶段,以获得" distinct"数,然后只是"两个" $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 }
}}
]
这是一个简单的代码,它更具有可扩展性和#34;作为个人" user_id"值最初包含在管道中的单独文档中。因此"第二" $group
(代替$ size的$项目)"计数"已在第一个分组键中确定的不同金额。
了解限制和陷阱,并编写良好的代码。