1

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]}}}}));

3 Answers 3

2

You can try this

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

Try it here

Sign up to request clarification or add additional context in comments.

Comments

1

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
        }
}

Comments

1

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];
  }
}

2 Comments

first i was doing like that but what about speed isnt it faster with mongo query ?
Ah, that could be true, but I do not know for sure. Honestly unless you're dealing with some mammoth data it shouldn't be an issue, and this is cleaner code-wise imo. Maybe try both out and see

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.