Let's now have a look at our books
document. We have an array of reviews. A review is an embedded object (notice the _id
parameter):
"reviews" : [ { "comment" : "Fast paced book!", "username" : "Gautam", "_id" : ObjectId("4e86f68bfed0eb0be0000018") }, { "comment" : "Excellent literature", "username" : "Tom", "_id" : ObjectId("4e86f6fffed0eb0be000001a") } ]
Let's try to retrieve reviews from "Gautam".
> db.books.find( { "reviews.username" : "Gautam")
The MongoDB classic act!
"reviews.username"
searches inside all the elements in the array for any field called"username"
, which has the specified value.
Of course, there are other conventional ways of searching inside arrays.
This is something similar to the IN
clause in SQL. Suppose we want to find documents for a specified number of values of a field, we can use the $in
operator. Let's see one of our book
objects:
> db.books.findOne()
{
"_id" : ObjectId("4e86e45efed0eb0be0000010"),
"author_id" : ObjectId("4e86e4b6fed0eb0be0000011"),
"category_ids" : [
ObjectId("4e86e4cbfed0eb0be0000012"),
ObjectId("4e86e4d9fed0eb0be0000013")
],
"name" : "Oliver Twist",
}
We do know that these are Category
objects referenced in some other collection. But that should not stop us from firing a direct query:
> db.books.find( { category_ids : { $in : [ ObjectId("4e86e4cbfed0eb0be0000012"), ObjectId("4e86e4d9fed0eb0be0000013") ] } } )
Alternatively, we could fire a NOT IN
query too, as follows:
> db.books.find( { category_ids : { $nin : [ ObjectId("555555555555555555555555"), ObjectId("666666666666666666666666") ] } } )
This would return all the books in the collection!
As we just saw $in
helps us search for documents that have any one of the values in the array. It's $all
that searches for documents that have all the values within the array in the field. Let's take this book
object again:
> db.books.findOne()
{
"_id" : ObjectId("4e86e45efed0eb0be0000010"),
"author_id" : ObjectId("4e86e4b6fed0eb0be0000011"),
"category_ids" : [
ObjectId("4e86e4cbfed0eb0be0000012"),
ObjectId("4e86e4d9fed0eb0be0000013")
],
"name" : "Oliver Twist",
}
Now, if we want to find books which belong to both the categories mentioned in the previous code, we fire the following query:
> db.books.find( { category_ids : { $all : [ ObjectId("4e86e4cbfed0eb0be0000012"), ObjectId("4e86e4d9fed0eb0be0000013") ] } } )
This will return all the books that are in both categories. However, unlike the earlier case of $in
, the following query will not return the previously mentioned book because it doesn't belong to all the categories mentioned next:
> db.books.find( { category_ids : { $all : [ ObjectId("4e86e4d9fed0eb0be0000011"), ObjectId("4e86e4d9fed0eb0be0000012"), ObjectId("4e86e4d9fed0eb0be0000013") ] } } )
18.119.112.7