MongoDB - Project only the matching element in an array
Asked Answered
D

1

12

How could I get one element from array from Mongo document with following structure:

{
 array : [ 
           {type: 'cat', name: 'George'}
           {type: 'cat', name: 'Mary'} 
           {type: 'dog', name: 'Steve'} 
           {type: 'dog', name: 'Anna'}  

         ]
}

For example I need to get Steve, in this case result must looks so:

{
 array : [ 
           {type: 'dog', name: 'Steve'}
 ] 
}

or so: {type: 'dog', name: 'Steve'}

I know how make it while publishing but I need to make it on client side where whole array is available, I could return this value from array using forEach, but I'm searching more elegant way (using Mongo query).

Dyer answered 20/12, 2015 at 20:13 Comment(1)
Possible duplicate of Retrieve only the queried element in an object array in MongoDB collectionBattik
A
11

Use the positional operator($) to project only the first matching sub document.

db.t.find({"array":{"type":"dog", "name":"Steve"}},{"array.$":1})

Using meteor, you would have to stick to aggregation, since the positional operator does not work:

db.t.aggregate([
{$match:{"array.type":"dog","array.name":"Steve"}},
{$unwind:"$array"},
{$match:{"array.type":"dog","array.name":"Steve"}}
])
Apogamy answered 20/12, 2015 at 20:32 Comment(4)
On server side query that looks like yours really returns array with matched elements, but on client side (minimongo) they returns whole array.Dyer
Not sure if the issue - github.com/meteor/meteor/issues/153 is still open. If it is you have to iterate through all your sub documents as in - #27951602Apogamy
@Dyer - you may need to stick to aggregating the result, in minimongo. See my updated answer.Apogamy
Sorry about late reply. Aggregate works for me, but it has only server side implementation and is non reactive.Dyer

© 2022 - 2024 — McMap. All rights reserved.