【问题标题】:Get list of child item ids that misses tag of parent in MongoDB获取 MongoDB 中缺少父项标记的子项 ID 列表
【发布时间】:2023-03-07 09:33:01
【问题描述】:

我想获取所有缺少标签的项目(或更好的项目 ID)。

如果子项缺少其父项的标记,则应将其输出。

文件如下所示:

[
  {
    id: 1,
    tags: [
      "a",
      "b"
    ],
    childs: [
      2,
      3
    ]
  },
  {
    id: 2,
    tags: [
      "a"
    ],
    childs: []
  },
  {
    id: 3,
    tags: [],
    childs: []
  },
  {
    id: 4,
    tags: [
      "c"
    ],
    childs: [
      5
    ]
  },
  {
    id: 5,
    tags: [
      "c"
    ],
    childs: []
  },
  {
    id: 6,
    tags: [
      "b"
    ],
    childs: [
      5
    ]
  },
  {
    id: 7,
    tags: [],
    childs: []
  },
]

现在我想按标签名称搜索以获取缺少标签的项目。

想要的结果应该是这样的:

检查标签“a”:

{
   id: 3,
   ...
}
 
or
 
{
   ids: [3]
}

检查标签“b”:

{
   id: 2,
   ...
},
{
   id: 3,
   ...
}

or
 
{
   ids: [2, 3]
}

我尝试使用查找和管道功能进行聚合,但没有成功。

[{
    $match: {
        tags: "a",
        childs: {
            $ne: []
        }
    }
}, {
    $lookup: {
        from: 'collection1',
        localField: 'childs',
        foreignField: 'id',
        as: 'childs_items',
        pipeline: [{
             $matching : {
                 "tags": {
                     $nin: "a"
                  }
             }
        }]
    }
}]

最好的方法是什么?

编辑:将最后两个文档的文档示例标签更改为“c” EDIT2:添加示例数据

【问题讨论】:

  • 感谢您的建议,但这不是我正在寻找的确切结果。我编辑了帖子以澄清问题。数据集有 n 个不同的标签,只有当父母有标签时,孩子也需要它。

标签: mongodb mongoose mongodb-query aggregation-framework


【解决方案1】:

可能会有其他简单的方法,但这是您更正的查询,

  • $match 情况如常,
  • $lookup 带管道,为 childs 定义变量以访问内部查找
  • $match条件,childs匹配与否,标签不等于指定字符
  • $project 创建 ids 数组,使用 $reduce
db.collection.aggregate([
  {
    $match: {
      tags: "b", // add your search
      childs: { $ne: [] }
    }
  },
  {
    $lookup: {
      from: "collection",
      let: { childs: "$childs" },
      as: "ids",
      pipeline: [
        {
          $match: {
            $expr: { $in: ["$id", "$$childs"] },
            tags: { $ne: "b" } // add your search
          }
        }
      ]
    }
  },
  {
    $project: {
      id: 1,
      ids: {
        $reduce: {
          input: "$ids",
          initialValue: [],
          in: { $concatArrays: ["$$value", ["$$this.id"]] }
        }
      }
    }
  }
])

Playground


您的最后一次编辑,您可以在上面示例中的 $lookup 之后使用 $unwind$group,删除 $project 阶段,

  { $unwind: "$ids" },
  {
    $group: {
      _id: null,
      ids: { $push: "$ids.id" }
    }
  }

Playground

【讨论】:

  • 太棒了,效果很好!谢谢!只是一个小问题:我该怎么做才能将结果 id 合并到一个数组中? (目前将为每个父级创建一个新的结果对象。我编辑了我的源文档)
  • 你可以做类似this的事情,我已经删除了$project,添加了$unwind和$group,按null分组并在ids数组中推送id
  • 这正是我想要的,非常感谢!
猜你喜欢
  • 1970-01-01
  • 2017-12-12
  • 2011-05-23
  • 1970-01-01
  • 1970-01-01
  • 2016-01-19
  • 1970-01-01
  • 2012-09-01
相关资源
最近更新 更多