MongoDB将文档与嵌套数组数组中的元素匹配

时间:2020-07-01 13:25:03

标签: mongodb aggregation-framework

我有一个类似以下的集合,目标是删除与其items.fruits.coloritems.fruits.type相匹配的每个文档 问题是,我需要找到同时具有两个条件的水果。

此外,如果items键为空,我需要选择该文档

这是我聚合的状态:

{
    type: "x"
    color: "red"
    items => [
        {
          item_id: 6   
          fruits: [
                {
                    color: "red",
                    type: "x"
                },
                {
                    color: "red",
                    type: "y"
                }
            ]
        },
        {
            item_id: 7   
            fruits: [
                {
                    color: "orange",
                    ref_id: "h"
                },
                {
                    color: "green",
                    ref_id: "x"
                }
            ]
        }
     ]
},{
    
    type: "o"
    color: "red"
    items => []

},{
    
    type: "w"
    color: "red"
    items => [
        {
            fruits: [
                {
                    type: "w",
                    color: "black"
                }
            ]
        }
    ]
}

因此第一个文档无效,因为items[fruits][0]的属性完全匹配。

但是第二个有效,因为items数组为空。

第三个也是有效的,因为其中没有匹配的水果。

我尝试的最后一个查询是:

$match: {
   "items.fruits": {
      $not: {
          $elemMatch: {
              color: "$color",
              type: "$type"
          }
      }
  }
}

但是它不起作用。而是显示所有文档。 (我认为这是因为$ color语句未被识别为变量)

2 个答案:

答案 0 :(得分:1)

如果要在没有具有给定颜色和类型的水果的任何文档上进行匹配,这应该起作用:

[{$match: {
   "items.fruits": {
      $not: {
          $elemMatch: {
              color: "red",
              type: "x"
          }
      }
  }
}}]

答案 1 :(得分:1)

我朝着另一个方向前进。我认为这可以帮助您入门,您可以添加其他$ project或$ group阶段以所需的格式获得最终结果。

[
{$unwind: {
  path: "$items"
}}, 
{$unwind: {
  path: "$items.fruits"
}}, 
{$addFields: {
  "items.fruits.isAMatch": 
    { $and: [
      {$eq: ["$items.fruits.type", "$type"] },
      {$eq: ["$items.fruits.color", "$color"] }
      ]
    }
}}, 
{$group: {
  _id: 
    {"id": "$_id",
    "itemid": "$items.item_id"
  },
  type: {$first: "$type"},
  color: {$first: "$color"},
  fruits: { $push: "$items.fruits" }
}}, {}]

第一阶段展开items数组。第二阶段展开水果数组。第三阶段检查水果和颜色是否匹配,并创建一个名为isAMatch的新字段以指示它们是否匹配。最后阶段根据_id和items.item_id将文档重新组合在一起。这些文档类似于原始文档,但是它们在Fruits数组对象中添加了字段,指示它们是否匹配。