MongoDB在嵌套数组聚合中查找

时间:2020-08-29 10:46:32

标签: javascript node.js mongodb mongoose aggregation-framework

我有下面解释的嵌套数组文档:

countries: [
  {
    "id": "id of country",
    "cities": [
      {
        "id": "id of city 1",
        "areas": [
          {
            "id": "id of area 1"
          },
          {
            "id": "id of area 2"
          },
          {
            "id": "id of area 3"
          },
          {
            "id": "id of area 4"
          }
        ]
      },
      {
        "id": "id of city 2",
        "areas": [
          {
            "id": "id of area 1"
          },
          {
            "id": "id of area 2"
          },
          {
            "id": "id of area 3"
          },
          {
            "id": "id of area 4"
          }
        ]
      }
    ]
  }
]

我的目标是使用$addFields添加一个字段,以指示给定的ID是否与区域ID匹配。

{$addFields: {
    isDeliveringToArea: {
      $in: [ObjectId('5db5d11cb18a2500129732a5'),'$countries.cities.areas.id']
    } 
}}

,但显然$in不适用于嵌套数组。 我希望类似find方法的方法Model.find({'countries.cities.areas.id': 'areaID'})可以在聚合中返回布尔值。

1 个答案:

答案 0 :(得分:2)

由于存在3个级别的嵌套数组,我们可以使用$map来实现此目的,该$map用于运行所有对象/修改对象。前一个$map用于遍历每个国家对象,第二个$anyElementTrue用于遍历每个国家内部的每个 city 对象>对象

更新1

由于您需要处理所有提交的文件,因此可以使用[ { "$addFields": { isDeliveringToArea: { $anyElementTrue: { $map: { input: "$countries", in: { $anyElementTrue: { $map: { input: "$$this.cities", in: { $in: [ "6", "$$this.areas.id" ] } } } } } } } } } ] 进行操作,这可以帮助我们确定条件下是否存在任何true元素,它将发出 true

工作Mongo play ground for overall country

SELECT *
FROM    products
WHERE   category_id IN
(
    SELECT category_id
    FROM `categories`
    WHERE FIND_IN_SET(`category_id`, (
    SELECT GROUP_CONCAT(Level SEPARATOR ',') FROM (
      SELECT @Ids := (
          SELECT GROUP_CONCAT(`category_id` SEPARATOR ',')
          FROM `categories`
          WHERE FIND_IN_SET(`parent_id`, @Ids)
      ) Level
      FROM `categories`
      JOIN (SELECT @Ids := 1) temp1
   ) temp2
))
)

我保留旧查询供您参考。 工作Mongo playground for each country object