问题:
我正在尝试获取文档列表,并为每个文档计算同一文档的嵌套数组中给定值的出现次数.
我有一个使用聚合框架的工作示例,但我想知道是否有更好的方法来完成同样的事情,所以我可以对不同的方法进行基准测试.
简化数据模型:
收藏“Raffles”中的单个文件:
{
"_id" : objectId,
"name" : string,
"ends_at" : ISODate/Timestamp,
...
"subscribers" : string[] //List of user ids
}
>集合包含代表抽奖/抽奖活动的文件,其中包括姓名和开始/结束日期.
>用户可以订阅抽奖活动.
>用户可以多次订阅相同的抽奖活动.
95%的读取查询将需要抽样数据,如名称,描述和有关订阅用户的日期信息.这就是为什么我决定将所有内容都放在一个抽奖文档中而不是:引用用户文档中的订阅抽奖活动或者有一个带有抽奖和订阅计数的单独收藏.
替代可能吗?:
subscriber数组是表示用户ID的字符串列表.这样添加订户就像推送新值一样简单.另一个选择是拥有一个像这样的对象数组并递增计数:
{
"subscribers: [
{
"id": objectId //User id
"count": integer //Number of subscriptions
},
...
]
}
预期结果:
预期的结果是使完整的抽奖文档成为给定用户具有多少订阅的附加值.
{
"_id" : objectId,
"name" : string,
"ends_at" : ISODate/Timestamp,
...
"subscriptions" : 3 //Number of entries for a given user
}
当前解决方案
我使用给定的用户ID
db.raffles.aggregate([
...
{
$project: {
"name" : 1,
"ends_at" :1,
...
"subscriptions" : {
$size : {
$filter : {
input: "$subscribers",
as: "user",
cond: {
$eq: ["$$user", <USER_ID>]
},
}
}
}
}
}
...
])
问题:
>还有其他/更好的方法来完成当前解决方案的结果吗?也许分组和总结或映射/减少?
>不仅要保留用户ID,还要保留具有用户ID和订阅计数的对象吗?
>如果未设置订阅数组,则当前解决方案将引发错误.有办法处理这个吗?
非常感谢您花时间阅读这篇长篇文章!
最佳答案 我会在订阅数组中保留用户ID和计数,并在与用户ID匹配时增加计数.
就像是
db.Raffles.update({"subscriptions.id":userid}, {$inc:{"subscriptions.$.count":1}}})
您可以使用以下查询访问代码.
db.Raffles.find({"subscriptions.id":userid},{"name":1,"ends_at":1,"subscriptions.$":1});