0

I have an object that has an array of sub objects on it:

    _id: "9",
        clients: [
            {
                id: 677,
                enabled: true,
                updated: 0,
                created: 1352416600
            },
            {
                id: 668,
                enabled: true,
                updated: 0,
                created: 1352416600
            }
        ],
        cloud: false,
        name: "love",
}

The user makes a request for images with client id 677, the above object will be returned

The user makes a request for images with client ids 677 and 668, the image above is returned

The user makes a request for images with client ids 677, 668, 690, the above image isn't returned

Im using PHP and Mongo DB. The MYSQL query that used to power this used to use a COUNT and sub query.

I have no idea where to even start tackling this in Mongo.

Any help appreciated.

3 Answers 3

2

To search into documents inside arrays, you can use dot notation and "$and" operator.

Syntax:

db.coll.find({"$and": [{"clients.id": <id1>}, {"clients.id": <id2>}, ... ]});

For you samples:

1) The user makes a request for images with client id 677 (for only one item, there is no need of "$and", but you can use anyway):

db.coll.find({"clients.id": 677});

or

db.coll.find({"$and": [{"clients.id": 677}]});

2) The user makes a request for images with client ids 677 and 668:

db.coll.find({"$and": [{"clients.id": 677}, {"clients.id": 668}]});

3) The user makes a request for images with client ids 677, 668, 690:

db.coll.find({"$and": [{"clients.id": 677}, {"clients.id": 668}, {"clients.id": 690}]});
Sign up to request clarification or add additional context in comments.

4 Comments

2) and 3) aren't correct as you can't have the same key multiple times in one JS object. Using $and like you show should be fine.
@johnnyHK, depending on the language you can. And seems that the mongo shell accept it as well. Notice that I'm not storing it, just using in a query. But yes, the "$and" options seems pretty better.
@MatheusdeOliveira The mongo shell will accept it, but what it's doing is only using one of the fields (probably the last one).
@JohnnyHK, you are right, I edited the answer to consider only the "$and". Sorry for the mistake.
1

For cases where you want to return docs where an array field contains each of a list of items you can use the $all operator.

So your three cases could be handled as:

1) The user makes a request for images with client id 677:

db.coll.find({'clients.id': 677});

2) The user makes a request for images with client ids 677 and 668:

db.coll.find({'clients.id': {$all: [677, 668]}});

3) The user makes a request for images with client ids 677, 668, and 690:

db.coll.find({'clients.id': {$all: [677, 668, 690]}});

Comments

0

There is a third and easier method.

db.foo.find({"clients.id":{$in:[677,688,690]}});

Hope this helps

/Nodex

Edit:

If you need to match the exact structure you can use $elemMatch for that

1 Comment

The "$in" operator would match any, not all. The $all operator or the $and seems to be the right ways.

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.