过滤子文档数组,同时仍返回父数据(如果为空)

时间:2014-05-13 16:01:15

标签: javascript arrays mongodb mongoose

我正在使用此问题How to filter array in subdocument with MongoDB

中的方法

除非数组中的所有元素都与测试匹配,否则它按预期工作。在这种情况下,我只得到一个没有父数据的空数组。

示例数据

 {
  "_id": "53712c7238b8d900008ef71c",
  "dealerName": "TestDealer",
  "email": "test@test.com",
  "address": {..},
  "inventories": [
      {
          "title": "active",
          "vehicles": [
            {
              "_id": "53712fa138b8d900008ef720",
              "createdAt": "2014-05-12T20:08:00.000Z",
              "tags": [
                 "vehicle"
               ],
               "opts": {...},
               "listed": false,
               "disclosures": {...},
               "details": {...}
           },
           {
              "_id": "53712fa138b8d900008ef720",
              "createdAt": "2014-05-12T20:08:00.000Z",
              "tags": [...],
              "opts": {...},
              "listed": true,
              "disclosures": {...},
              "details": {...}
            }
         ]
     },
     {
         "title": "sold",
         "vehicles": []
     }
  ]
}

尝试做

在我的查询中,我想返回用户(文档)顶级信息(dealerName,电子邮件)和一个名为vehicle的属性,其中包含“活动”库存中列出的属性设置为{{1 }}

我怎么做

这是我的查询。 (我使用Mongoose但主要使用本地Mongo功能)

true

问题

起初,我认为我的查询很好,但是,如果没有车辆被标记为 { $match: email: params.username } { $unwind: '$inventories' } { $match: 'inventories.title': 'active' } { $unwind: '$inventories.vehicles' } { $match: 'inventories.vehicles.listed': $eq: true } { $group: _id: '$_id' dealerName: $first: '$dealerName' email: $first: '$email' address: $first: '$address' vehicles: $push: '$inventories.vehicles' } ,则查询只返回一个空数组。这是有道理的,因为

listed

不匹配任何东西,但我仍然希望获得dealerName以及他的电子邮件

如果没有车辆匹配,则希望输出

      {
        $match:
          'inventories.vehicles.listed':
            $eq: true
      }

实际输出

[{"dealerName": "TestDealer", "email": "test@test.com", vehicles : []}]

1 个答案:

答案 0 :(得分:5)

在这种情况下,您可以使用$ redact而不是$ match,就像这样

db.collectionName.aggregate({
  $redact:{
    $cond:{ 
       if:{$and:[{$not:"$dealerName"},{$not:"$title"},{$eq:["$listed",false]}, 
       then: "$$PRUNE", 
       else: "$$DESCEND" 
    }
  }
})

我们需要第一个条件跳过顶级文件,第二个条件跳过第二个级别,第三个条件跳过修剪车辆。在这种情况下,无需展开

还有一件事:$ redact仅在2.6

中可用