Mongodb 如果只有嵌套文档匹配结果,是否可以排除根文档?

Mongodb Is it possible to exclude the root document if only a nested document matches the result?

我有一组文档,其中包含同一文档的一组嵌套修订版。我需要执行 returns 仅匹配集的搜索查询,包括匹配的父项。以下是数据的简化示例。

{
"title_number": "46345734",
"status": "applied",
"updated": "02/04/2022",
"rev_num": 1,
"revs": [
  {
    "title_number": "46345734",
    "status": "unapplied",
    "updated": "02/06/2022",
    "rev_num": 2
  }]
},
{
"title_number": "46345802",
"status": "unapplied",
"updated": "02/05/2022",
"rev_num": 1,
"revs": [
  {
    "title_number": "46345802",
    "status": "applied",
    "updated": "02/05/2022",
    "rev_num": 2
  },
  {
    "title_number": "46345802",
    "status": "applied",
    "updated": "02/06/2022",
    "rev_num": 3
  }]
}

在一个查询中,我想查找状态为“未应用”的所有文档,只返回与状态匹配的嵌套文档,如果也匹配则保留或删除父文档。

下面是我期望查询最初看起来如何的示例,以及 运行 根据提供的示例数据时的预期结果。

titles.find({
  "$and": [{
    "$or": [
      {"status": "applied"},
      {"revs.status": "applied"}
    ]
  }]
})

预期(想要)结果

{
"title_number": "46345734",
"status": "applied",
"updated": "02/04/2022",
"rev_num": 1,
"revs": [],
},
{
  "title_number": "46345802",
  "status": "applied",
  "updated": "02/05/2022",
  "rev_num": 2
},
{
  "title_number": "46345802",
  "status": "applied",
  "updated": "02/06/2022",
  "rev_num": 3
}

在第一个结果中,父状态匹配,但子不匹配,因此只返回父。在第二个结果中,父级不匹配,但是,两个嵌套文档匹配,所以只返回它们。

在阅读了大量关于聚合、元素匹配等的帖子后,我已经能够得到一些零碎的信息,但我的情况似乎非常明显或相当独特。

在此先感谢您的帮助。

使用 aggregate 并首先 $filter revs with applied status and then $push 应用文档来分隔数组,然后 revs 应用到另一个数组,最后将两个数组混合为一个。

你可以在这里测试mongodb playground

titles.aggregate([
  {
    "$addFields": {
      "revs": {
        $filter: {
          input: "$revs",
          as: "rev",
          cond: {
            $eq: [
              "$$rev.status",
              "applied"
            ]
          }
        }
      }
    }
  },
  {
    $group: {
      _id: null,
      applied_doc: {
        $push: {
          $cond: [
            {
              $eq: [
                "$status",
                "applied"
              ]
            },
            {
              _id: "_id",
              title_number: "$title_number",
              status: "$status",
              updated: "$updated",
              rev_num: "$rev_num",
              revs: "$revs"
            },
            "$$REMOVE"
          ]
        }
      },
      applied_sub_doc: {
        $push: "$revs"
      }
    },
    
  },
  // flatten array in $applied_sub_doc prop
  {
    $set: {
      applied_sub_doc: {
        $reduce: {
          input: "$applied_sub_doc",
          initialValue: [],
          in: {
            $concatArrays: [
              "$$value",
              "$$this"
            ],
            
          },
          
        },
        
      },
      
    },
    
  },
  {
    $project: {
      mixedDocs: {
        $concatArrays: [
          "$applied_doc",
          "$applied_sub_doc"
        ],
        
      },
      
    },
    
  },
  {
    $unwind: "$mixedDocs",
    
  },
  {
    $replaceWith: "$mixedDocs",
    
  },
  
])