Retrieve field value from array of sub document

2019-03-06 14:14发布

问题:

I have some documents like this:

{
  "hash": "14a076f9f6cecfc58339330eeb492e267f63062f6d5f669c7cdbfecf9eb4de32",
  "started_services": [],
  "deleted_files": [],
  "software": { 
      "adobe" : {
          "licenses" : [
                  { "key": "2384723",
                    "date": "26-10-2012"
                  },
                  { "key": "23888823",
                    "date": "09-11-2012"
                  }
          ]
      }
   }
}

How do I retrieve just the hash value and the list of "key" values?

I did the following, but, as you see, the result has the entire path which I do not want.

> db.repository.find({"$and": [{"datetime_int": {"$gte": 1451952000}},{"software.adobe.licenses.key" : { $exists : true}}]}, {hash:1, "software.adobe.licenses.key":1, _id:0}).limit(10)

{ "hash" : "a1532e0609aaf6acfa9e505e93af0bee0856a9a67398aeaa72aa6eb2fffd134e", "software" : { "adobe" : { "licenses" : [ { "key" : "2008350" }, { "key" : "2018350" }, { "key" : "2028350" }, { "key" : "2038350" }, { "key" : "2048350" }, { "key" : "2058350" }, { "key" : "2068350" }, { "key" : "2078350" }...]}}}

The result I want should look like this:

{"hash": "a1532e0609aaf6acfa9e505e93af0bee0856a9a67398aeaa72aa6eb2fffd134e",
 "key": ["2008350", "2018350", "2028350", "2038350", "2048350", "2058350", "2068350", "2078350"]
}

How do I do that?

回答1:

You can do this with the aggregation framework.

db.repository.aggregate([ 
    { "$match": { 
        "datetime_int": { "$gte": 1451952000 }, 
        "software.adobe.licenses.key" : { "$exists" : true } 
    }}, 
    { "$project": { 
        "hash": 1, 
        "key": { 
            "$map": { 
                "input": "$software.adobe.licenses", 
                "as": "soft", 
                "in": "$$soft.key"
            }
        }
    }}
])

Starting From MongoDB 3.2 you can directly project the sub-document array field.

{ "$project": { "hash": 1, "key": "$software.adobe.licenses.key"}}


回答2:

db.key.aggregate((
{ "$match": { 
        "datetime_int": { "$gte": 1451952000 }
        }},
{"$unwind":"$software.adobe.licenses"},
{"$project":{"key":"$software.adobe.licenses.key", "hash":1, "_id":0}}
))

outputs the following :

{ "hash" : "14a076f9f6cecfc58339330eeb492e267f63062f6d5f669c7cdbfecf9eb4de32", "key" : [ "2384723", "23888823" ] }