1

An example of the schema i have;

{ "_id" : 1234,
  “dealershipName”: “Eric’s Mongo Cars”,
  “cars”: [
         {“year”: 2013,
           “make”: “10gen”,
           “model”: “MongoCar”,
           “vin”: 3928056,
           “mechanicNotes”: “Runs great!”},
         {“year”: 1985,
          “make”: “DeLorean”,
          “model”: “DMC-12”,
          “vin”: 8056309,
          “mechanicNotes”: “Great Scott!”}
         ]
  }

I wish to query and return only the value "vin" in "_id : 1234". Any suggestion is much appreciated.

user44552
  • 153
  • 1
  • 10
  • `_id:1234` contains two cars with different `vin`s. What exactly do you need as a result? An array like `[3928056, 8056309]`? Concrete examples are always helpful. – mnemosyn Mar 31 '14 at 19:39
  • Yeah, I'm assuming you want the `_id` AND the `vin` fields, right? – AlbertEngelB Nov 04 '14 at 02:28

2 Answers2

2

You can use the field selection parameter with dot notation to constrain the output to just the desired field:

db.test.find({_id: 1234}, {_id: 0, 'cars.vin': 1})

Output:

{
    "cars" : [ 
        {
            "vin" : 3928056
        }, 
        {
            "vin" : 8056309
        }
    ]
}

Or if you just want an array of vin values you can use aggregate:

db.test.aggregate([
    // Find the matching doc
    {$match: {_id: 1234}},
    // Duplicate it, once per cars element
    {$unwind: '$cars'},
    // Group it back together, adding each cars.vin value as an element of a vin array
    {$group: {_id: '$_id', vin: {$push: '$cars.vin'}}},
    // Only include the vin field in the output
    {$project: {_id: 0, vin: 1}}
])

Output:

{
    "result" : [ 
        {
            "vin" : [ 
                3928056, 
                8056309
            ]
        }
    ],
    "ok" : 1
}
JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
  • 1
    Just to add to this answer, the projection part of the query (`{'cars.vin': 1}`) comes with the `_id` by defualt. You can remove it if you do this: `{vin: true, _id: false}` The values for the projection just go off of JS's truthy/ falsy values. – AlbertEngelB Nov 04 '14 at 02:29
  • Right, I was just making that change. – JohnnyHK Nov 04 '14 at 02:31
  • @JohnnyHK Awesome, is there an easy way to filter the results by subdocument? – Stephen Punwasi Nov 04 '14 at 12:59
  • @StephenP. The easiest way to filter by subdoc is to add a `$match` between the `$unwind` and `$group`. See [this question](http://stackoverflow.com/questions/3985214/retrieve-only-the-queried-element-in-an-object-array-in-mongodb-collection) for more options. – JohnnyHK Nov 04 '14 at 13:27
0

If by query, you mean get the values of the vins in javascript, you could read the json into a string called theString (or any other name) and do something like:

var f = [], obj = JSON.parse(theString);

obj.cars.forEach(function(item) { f.push(item.vin) });

If your json above is part of a larger collection, then you'd need an outer loop.

grant
  • 852
  • 1
  • 8
  • 21