Retrieve multiple queried elements in an object array in MongoDB collection

谁说我不能喝 提交于 2020-01-16 12:45:07

问题


I want to find all zone data with "AHU":"C". First, I query without projection and get these.

> db.buildings.find({"zone.AHU": "C"}).pretty()
{
    "_id" : ObjectId("5aba4460a042dc4a2fdf26cd"),
    "name" : "Test Street",
    "coordinate" : [
        12,
        31
    ],
    "yearlyEnergyCost" : 1444,
    "zone" : [
        {
            "name" : "AHU-C-Z2",
            "_id" : ObjectId("5aba4460a042dc4a2fdf26ce"),
            "AHU" : "C",
            "precooling" : [ ],
            "subZone" : [ ]
        },
        {
            "name" : "AHU-D-Z1",
            "_id" : ObjectId("5abc7528100730697163a3ab"),
            "AHU" : "D",
            "precooling" : [ ],
            "subZone" : [ ]
        },
        {
            "name" : "AHU-C-Z1",
            "AHU" : "C",
            "_id" : ObjectId("5ac09c898249affa03506eff"),
            "precooling" : [ ],
            "subZone" : [ ]
        },
        {
            "name" : "AHU-C-Z3",
            "AHU" : "C",
            "_id" : ObjectId("5ac09c898249affa03506efe"),
            "precooling" : [ ],
            "subZone" : [ ]
        }
    ],
    "__v" : 2
}

However, when I use $elemMatch, it only returns the first zone element with "AHU":"C"

> db.buildings.find({"zone.AHU": "C"}, {_id: 0, zone: {$elemMatch: {AHU: "C"}}}).pretty()
{
    "zone" : [
        {
            "name" : "AHU-C-Z2",
            "_id" : ObjectId("5aba4460a042dc4a2fdf26ce"),
            "AHU" : "C",
            "precooling" : [ ],
            "subZone" : [ ]
        }
    ]
}

From the doc, I realised that $elemMatch (projection) only retrieve the first one, but how can I retrieve all corresponded (AHU-C-Z1, AHU-C-Z2, AHU-C-Z3)? Thanks.

This is the collection:

{  
   "_id":{  
      "$oid":"5aa65bc96996e045104116e7"
   },
   "name":"Talker Street",
   "coordinate":[  
      11.82,
      -9.26
   ],
   "yearlyEnergyCost":100,
   "zone":[  
      {  
         "name":"AHU-B-Z1",
         "_id":{  
            "$oid":"5aa65bc96996e045104116e8"
         },
         "precooling":[  
            {  
               "_id":{  
                  "$oid":"5aa73a7d2f991a657fd52c7e"
               },
               "resultPrecool":{  
                  "$oid":"5aa73a7d2f991a657fd52b5d"
               },
               "dateRun":{  
                  "$date":"2018-03-14T00:00:00.000+0000"
               },
               "lastUpdated":{  
                  "$date":"2018-03-13T02:41:02.086+0000"
               }
            }
         ]
      },
      {  
         "name":"AHU-B-Z2",
         "_id":{  
            "$oid":"5aa9f1f8131e6412c17d71d3"
         },
         "precooling":[  

         ]
      },
      {  
         "name":"AHU-B-Z3",
         "_id":{  
            "$oid":"5aa9f1f8131e6412c17d71d2"
         },
         "precooling":[  

         ]
      }
   ],
   "__v":19
}{  
   "_id":{  
      "$oid":"5aba4460a042dc4a2fdf26cd"
   },
   "name":"Test Street",
   "coordinate":[  
      12,
      31
   ],
   "yearlyEnergyCost":1444,
   "zone":[  
      {  
         "name":"AHU-C-Z2",
         "_id":{  
            "$oid":"5aba4460a042dc4a2fdf26ce"
         },
         "AHU":"C",
         "precooling":[  

         ],
         "subZone":[  

         ]
      },
      {  
         "name":"AHU-D-Z1",
         "_id":{  
            "$oid":"5abc7528100730697163a3ab"
         },
         "AHU":"D",
         "precooling":[  

         ],
         "subZone":[  

         ]
      },
      {  
         "name":"AHU-C-Z1",
         "AHU":"C",
         "_id":{  
            "$oid":"5ac09c898249affa03506eff"
         },
         "precooling":[  

         ],
         "subZone":[  

         ]
      },
      {  
         "name":"AHU-C-Z3",
         "AHU":"C",
         "_id":{  
            "$oid":"5ac09c898249affa03506efe"
         },
         "precooling":[  

         ],
         "subZone":[  

         ]
      }
   ],
   "__v":2
}{  
   "_id":{  
      "$oid":"5aba46c41c8d5e4b52462aea"
   },
   "name":"123123",
   "coordinate":[  
      12,
      31
   ],
   "yearlyEnergyCost":12321,
   "zone":[  
      {  
         "name":"123423",
         "_id":{  
            "$oid":"5aba46c41c8d5e4b52462aeb"
         },
         "precooling":[  

         ],
         "subZone":[  

         ]
      }
   ],
   "__v":0
}

回答1:


You can use $redact operator:

db.buildings.aggregate([
{$match:{"zone.AHU":{$exists:true}}},
{$redact:{
  $cond:{
       if:{$or:[{$eq:["$AHU","C"]},{$not: "$AHU"}]},
       then:"$$DESCEND",
       else:"$$PRUNE"   
     }  
   }}  
]) 

Remember {$not: "$AHU"} is important to be included so that top element will not be excluded. If not added, top element will be skipped and hence skipping the entire embedded document.

Output:

{
"_id" : ObjectId("5aba4460a042dc4a2fdf26cd"),
"name" : "Test Street",
"coordinate" : [ 
    12, 
    31
],
"yearlyEnergyCost" : 1444,
"zone" : [ 
    {
        "name" : "AHU-C-Z2",
        "_id" : ObjectId("5aba4460a042dc4a2fdf26ce"),
        "AHU" : "C",
        "precooling" : [],
        "subZone" : []
    }, 
    {
        "name" : "AHU-C-Z1",
        "AHU" : "C",
        "_id" : ObjectId("5ac09c898249affa03506eff"),
        "precooling" : [],
        "subZone" : []
    }, 
    {
        "name" : "AHU-C-Z3",
        "AHU" : "C",
        "_id" : ObjectId("5ac09c898249affa03506efe"),
        "precooling" : [],
        "subZone" : []
    }
],
"__v" : 2
}


来源:https://stackoverflow.com/questions/49611773/retrieve-multiple-queried-elements-in-an-object-array-in-mongodb-collection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!