I am new to NoSQL
and MongoDB
and I am a little puzzled on what type of queries I can do and how to do them. my knowledge is limited to simpler queries
I would like to make what I think its a complicated query within MongoDB
instead of using PHP
to sort it but I do not know if it is possible or how to do it.
I have a tag
field within my collection that is an array
. {tag: ["blue","red","yellow","green","violet"]}
.
First level problem: Let says I want to find all birds
that have the tag
blue & yellow & green
, where blue
is a must have tag
and any other colours are optional.
Second level problem: Then I would like to order the query so that the birds
that have all the queried colours appear first.
Is it possible to create this query in mongoDB? and if it is How could I do it?
Most of this you will have to do in your application. In order to find all documents where a bird has the tag "blue", you can do this:
db.collection.find( { tag: "blue" } );
Which colours are optional doesn't matter, as you have to find by the required tag anyway.
After finding them, you need to do a sort. But sorting like you want (by their 3 colours) is not something you can do in MongoDB, and something you will have to do in PHP instead.
You can use aggregation framework. So for the next dataset:
{ "_id":ObjectId(...), "bird":1, "tags":["blue","red","yellow","green","violet"]}
{ "_id":ObjectId(...), "bird":2, "tags":["red","yellow","green","violet"] }
{ "_id":ObjectId(...), "bird":3, "tags":["blue","yellow","violet"] }
{ "_id":ObjectId(...), "bird":4, "tags":["blue","yellow","red","violet"] }
{ "_id":ObjectId(...), "bird":5, "tags":["blue"] }
we can apply next query:
colors = ["blue","red","yellow","green"];
db.birds.aggregate(
{ $match: {tags: 'blue'} },
{ $project: {_id:0, bird:1, tags:1} },
{ $unwind: '$tags' },
{ $match: {tags: {$in: colors}} },
{ $group: {_id:'$bird', score: {$sum:1}} },
{ $sort: {score:-1} },
{ $project: {bird:'$_id', score:1, _id:0} }
)
and will get result like this:
{
"result" : [
{ "score" : 4, "bird" : 1 },
{ "score" : 3, "bird" : 4 },
{ "score" : 2, "bird" : 3 },
{ "score" : 1, "bird" : 5 }
],
"ok" : 1
}