Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Query to retrieve multiple items in an array

Tags:

mongodb

If I have the following payload:

{
    "objs": [
        {  "_id": "1234566", "some":"data", "key": "one" },
        {  "_id": "1234576", "some":"data", "key": "one" },
        {  "_id": "2345666", "some":"otherdata", "key": "two" },
        {  "_id": "4566666", "some":"yetotherdata", "key": "three" },
    ]
}

How can I return all objects (objs) with the following:

key:  "one"
_id: [1234566, 1234576]

Thanks

like image 983
Paul Avatar asked Aug 28 '26 07:08

Paul


2 Answers

The find() query returns all the objs that have the sub documents that match both these conditions.

var input = ["1234566","1234576"];
db.collection.find({$and:[{"objs._id":{$in:input}},{"objs.key":"one"}]})

If you want to get the redacted documents inside the objs array, You can achieve this using the aggregate pipeline operations.

  • Define a variable to hold the input values.
  • $unwind by objs elements, this gives you seperate documents for each element in the objs array.
  • $match only those documents that match the selection criteria.
  • $group by "_id" of the document which is autogenerated by mongo.
  • $project the required fields.

The Code:

var input = ["1234566","1234576"];
db.collection.aggregate([
{$unwind:"$objs"},
{$match:{"objs._id":{$in:input},"objs.key":"one"}},
{$group:{"_id":"_id","objs":{$push:"$objs"}}},
{$project:{"_id":0,"objs":1}}
])

o/p:

{ "objs" : 
         [ { "_id" : "1234566", "some" : "data", "key" : "one" },
           { "_id" : "1234576", "some" : "data", "key" : "one" } ] }
like image 174
BatScream Avatar answered Aug 30 '26 08:08

BatScream


You can't. MongoDB returns the document that matches the query conditions, not individual pieces that match the query conditions. You can suppress or include fields of the matching documents with projection, but you cannot (as of 2.6) return an array restricted just to contain elements that matched conditions on the array. You can return just the first such match with $

db.collection.find(
    { "objs" : { "$elemMatch" : { "_id" : { "$in" : [1234566, 1234576] }, "key" : "one" } } }, // query
    { "_id" : 0, "objs.$" : 1 } // projection
)

If you want to return all matching objs elements, most likely you should make each subdocument in the objs array into its own document in the collection.

like image 44
wdberkeley Avatar answered Aug 30 '26 07:08

wdberkeley



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!