azz0r
azz0r

Reputation: 3311

Mongo, match array of arrays

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.

Upvotes: 0

Views: 234

Answers (3)

MatheusOl
MatheusOl

Reputation: 11815

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

Upvotes: 2

JohnnyHK
JohnnyHK

Reputation: 311835

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

Upvotes: 1

Alex
Alex

Reputation: 21

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

Upvotes: 0

Related Questions