l0veisreal
l0veisreal

Reputation: 179

Mongodb Meteor Querying Array and getting object

I have one collection called Resources with documents inside:

{
    "_id" : "fGR4ECcw5p2HFgxd3",
    "ownerId" : "J8MpsWChPQdET6jwQ",
    "inventory" : [ 
        {
            "_id" : ObjectId("5b537ef5895adfeae037e0a4"),
            "quantity" : 17
        }, 
        {
            "_id" : ObjectId("5b537d9c895adfeae037dbd2"),
            "quantity" : 6
        }, 
        {
            "_id" : ObjectId("5b5868e081702f675304290e"),
            "quantity" : 26
        }, 
        {
            "_id" : ObjectId("5b5eba8276dd90bd75e27f13"),
            "quantity" : 85
        }, 
        {
            "_id" : ObjectId("5b5ee58176dd90bd75e2f35f"),
            "quantity" : 5
        }, 
        {
            "_id" : ObjectId("5b62275686f92e050a9d50b2"),
            "quantity" : 3
        }
    ]
}

What i am trying to do is get object of inventory array with that objects id

I feel like this should work but its not

Resources.findOne({ownerId:userid,"inventory._id":ObjectId})

my expected output for example:

 {
            "_id" : ObjectId("5b537ef5895adfeae037e0a4"),
            "quantity" : 17
        } 

I also tried this:

 console.log(Resources.findOne({ownerId:userid},{fields:{inventory:{$elemMatch:{_id:ids[i]}}}}));

Upvotes: 1

Views: 332

Answers (3)

Ashh
Ashh

Reputation: 46441

You can try this

db.collection.find({
  "ownerId": "J8MpsWChPQdET6jwQ"
},
{
  "inventory": {
    "$elemMatch": {
      "_id": ObjectId("5b537ef5895adfeae037e0a4")
    }
  }
})

Try it here

Upvotes: 2

Kieran McWilliams
Kieran McWilliams

Reputation: 101

Assuming you just want to access that data, there is an easier way.

You can grab the resource, then run through it's inventory and find the object you want.

Try something like this (userId and objectId are your input/searching variables. I also camel-cased them):

var userId = "some id";
var objectId = "some id";

var resource = Resources.findOne({"ownerId": userId});
var inventory = resource.inventory;

var output = {};

for(var i = 0; i < inventory.length; i++) {
  if(inventory[i]._id == objectId) {
    output = inventory[i];
  }
}

Upvotes: 1

Carlo Espino
Carlo Espino

Reputation: 1384

You can use MongoDB aggregations as per documetation:

Aggregation operations process data records and return computed results. Aggregation operations group values from multiple documents together, and can perform a variety of operations on the grouped data to return a single result.

Please make sure meteor has proper interface to MongoDB aggregations i.e. Resources.aggregate

Later mongo shell query works on my machine with the document you mentioned.

db.test.aggregate([
    {
        $match: {
            ownerId: "J8MpsWChPQdET6jwQ",
            inventory: {
                $elemMatch: {
                    "_id": ObjectId("5b537ef5895adfeae037e0a4")
                }
            }
        }
    },
    {
        $project: {
            _id: 0,
            inventory: 1
        }
    },
    {
        $project: {
            result:
            {
                $arrayElemAt: [
                    {
                        $filter: {
                            input: "$inventory",
                            as: "product",
                            cond: {
                                $eq: [
                                    "$$product._id",
                                    ObjectId("5b537ef5895adfeae037e0a4")
                                ]
                            }
                        }
                    },
                    0
                ]
            }
        }
    }
])

Result is:

{
        "result" : {
                "_id" : ObjectId("5b537ef5895adfeae037e0a4"),
                "quantity" : 17
        }
}

Upvotes: 1

Related Questions