簡體   English   中英

過濾子文檔數組,同時如果為空仍返回父數據

[英]Filter subdocument array while still returning parent data if empty

我正在使用此問題中的方法如何使用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,email)和一個名為Vehicles的屬性,該屬性包含“活動”庫存中的所有載具,且這些載具的屬性都設置為true

我怎么了

這是我的查詢。 (我使用Mongoose,但主要使用本地的Mongo功能)

      {
        $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 ,則查詢只會返回一個空數組。 這是有道理的,因為

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

沒有任何匹配項,但我仍然想獲得DealerName以及他的電子郵件

如果沒有車輛匹配則需要的輸出

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

實際輸出

[]

在這種情況下,您可以使用$ redact而不是$ match,就像這樣

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

我們需要第一個條件跳過頂級文檔,第二個條件跳過第二級文檔,第三個條件對車輛進行修剪。 在這種情況下, 無需$ unwind

還有一件事:$ redact僅在2.6中可用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM