【问题标题】:Group if only specific condition fulfil in MongoDB如果仅在 MongoDB 中满足特定条件,则分组
【发布时间】:2021-05-10 13:48:37
【问题描述】:

如果组事件的数量超过 3 个,我想通过它们的pid(仅组)对一些特定记录进行分组。

示例:

这里group (pid: 200) 的事件数为 4,必须分组。

- Events -
----------
{_id: ObjectId, type: 'private', pid: 140, data: {...}},
{_id: ObjectId, type: 'group', pid: 800, data: {...}}, // << group 800
{_id: ObjectId, type: 'group', pid: 200, data: {...}}, // << group 200
{_id: ObjectId, type: 'group', pid: 200, data: {...}}, // << group 200
{_id: ObjectId, type: 'private', pid: 140, data: {...}},
{_id: ObjectId, type: 'group', pid: 200, data: {...}}, // << group 200
{_id: ObjectId, type: 'group', pid: 200, data: {...}}, // << group 200
{_id: ObjectId, type: 'private', pid: 130, data: {...}},

这里group (pid: 200) 被分组,is_too_long: true 被添加到记录中。并且group (pid: 800) 没有按预期分组。

- Results -
-----------
{_id: ObjectId, type: 'private', pid: 140, data: {...}},
{_id: ObjectId, type: 'group', pid: 800, data: {...}, is_too_long: false}, // << group 800
{_id: ObjectId, type: 'private', pid: 140, data: {...}},
{_id: ObjectId, type: 'group', pid: 200, is_too_long: true}}, // << group 200 (with [is_too_long: true])
{_id: ObjectId, type: 'private', pid: 130, data: {...}, is_too_long: false},

我尝试了其他一些查询,但都没有成功!请帮帮我!

【问题讨论】:

    标签: mongodb mongoose group-by aggregation-framework


    【解决方案1】:
    • $facetprivategroup 文件分开,
    • $group by pid 并将文档分组到一个数组中
    • $cond 检查条件,如果分组文档大于或等于 3,则从数组中切片单个元素并设置 is_too_long: true 否则为 false
    • $map 迭代 docs 数组的循环并放入布尔属性 is_too_long
    • $unwind解构root数组
    • $replaceRootroot 对象替换为根
    • $concatArrays、concat privategroup 数组
    • $unwind解构root数组
    • $replaceRoot 替换根目录下的 root 对象
    db.collection.aggregate([
      {
        $facet: {
          private: [{ $match: { type: "private" } }],
          group: [
            { $match: { type: "group" } },
            {
              $group: {
                _id: "$pid",
                root: { $push: "$$ROOT" }
              }
            },
            {
              $project: {
                root: {
                  $cond: [
                    { $gte: [{ $size: "$root" }, 3] },
                    {
                      is_too_long: true,
                      docs: { $slice: ["$root", 1] }
                    },
                    {
                      is_too_long: false,
                      docs: "$root"
                    }
                  ]
                }
              }
            },
            {
              $project: {
                root: {
                  $map: {
                    input: "$root.docs",
                    in: { $mergeObjects: ["$$this", { is_too_long: "$root.is_too_long" }] }
                  }
                }
              }
            },
            { $unwind: "$root" },
            { $replaceRoot: { newRoot: "$root" } }
          ]
        }
      },
      { $project: { root: { $concatArrays: ["$private", "$group"] } } },
      { $unwind: "$root" },
      { $replaceRoot: { newRoot: "$root" } }
    ])
    

    Playground

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-26
      • 2021-11-11
      • 2017-04-30
      • 2023-03-13
      • 2014-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多