代码之家  ›  专栏  ›  技术社区  ›  iivannov

MongoDB-过滤后获取嵌套数组大小的文档

  •  4
  • iivannov  · 技术社区  · 6 年前

    问题:

    我试图得到一个文档列表,并为每个文档计算同一文档的嵌套数组中给定值的出现次数。

    我有一个使用聚合框架的工作示例,但是我想知道是否有更好的方法来完成相同的任务,这样我就可以对不同的方法进行基准测试。

    简化数据模型:

    {
      "_id" : objectId,
      "name" : string,
      "ends_at" : ISODate/Timestamp,
       ...
      "subscribers" : string[] //List of user ids
    }
    
    • 这些集合由代表抽奖/抽奖的文件组成,其中包含名称和开始/结束日期。
    • 用户可以订阅抽奖。

    95%的读取查询将需要抽奖数据,如姓名、描述和日期+有关订阅用户的信息。这就是为什么我决定把所有的东西都放在一个抽奖文档中,而不是:在用户文档中引用订阅的抽奖,或者单独收集一个包含抽奖和订阅计数的集合。

    或许可以选择

    这个 subscribers

    {
      "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筛选嵌套数组之后,我将获得大小<用户ID>

    db.raffles.aggregate([
        ...
        {
            $project: {
                "name" : 1,
                "ends_at" :1,
                 ...
                "subscriptions" : {
                     $size : {
                        $filter : {
                            input: "$subscribers",
                            as: "user",
                            cond: {
                                $eq: ["$$user", <USER_ID>]
                            },
                        }
                     }
                }
            }
        }
        ...
    ])
    

    问题:

    • 是否有其他/更好的方法来实现当前解决方案的结果?也许分组和总结或者映射/减少?

    • 不仅要保留用户id,还要保留具有用户id和订阅计数的对象,这值得吗?

    • subscriptions 未设置数组。有办法处理吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   s7vr    6 年前

    我将在订阅数组中保留用户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});