简体   繁体   中英

Using $unwind with nested subdocuments

I have a collection with the following structure:

{
   {
     node: 'ST20'
     Ds:{
          699:{
                   TotCM: 300
                   Docsis20: 200
                   Docsis30: 100
              }
          705:{
                   TotCM: 250
                   Docsis20: 150
                   Docsis30: 100
              }

        }
   }
   {
     node: 'ST21'
Ds:{
          651:{
                   TotCM: 200
                   Docsis20: 100
                   Docsis30: 100
              }
          699:{
                   TotCM: 100
                   Docsis20: 0
                   Docsis30: 100
              }

        }
   }
}

As you can see, I have a document that represents a node. Each node, has different channels. My objective is see how many cablemodems I have in each channel. From upfront, I don't know the channels that I have in each node. So I would like to have something like this:

{ node: 'ST20', Ds: 699, TotCM: 300, Docsis20: 200, Docsis30:100 }
{ node: 'ST20', Ds: 705, TotCM: 250, Docsis20: 150, Docsis30:100 }
{ node: 'ST21', Ds: 651, TotCM: 200, Docsis20: 100, Docsis30:100 }
{ node: 'ST21', Ds: 699, TotCM: 100, Docsis20: 0,   Docsis30:100 }

I tried the following query:

db.statsNodos.aggregate(
{ $project: {_id:0,Ds:1,node:1}},
{ $unwind: "$Ds"}
).pretty()

But I get the original document. And, as you can see, they are nested documents and not an array of documents. Maybe I don't have to use $unwind and there is another way to get this. Can you tell me?

Given your example document structure :

{ node: 'ST21', 
  Ds: {
       "651":{ TotCM: 200, Docsis20: 100, Docsis30: 100 },
       "699":{ TotCM: 100, Docsis20: 0, Docsis30: 100 }
       }
}

You can utilise operator $objectToArray to pivot your field channels name into value. For example:

{"$project": {
               "_id": 0, 
               "node": 1, 
               "tmp": { "$objectToArray": "$Ds" }
             }
}, 
{"$unwind": "$tmp" }, 
{"$project": { 
               "node": 1, 
               "Ds": "$tmp.k", 
               "TotCM": "$tmp.v.TotCM", 
               "Docsis20": "$tmp.v.Docsis20", 
               "Docsis30": "$tmp.v.Docsis30"
             }
}

I would also recommend to reconsider your MongoDB Data Schema for easier querying.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM