1

I have document with nested document reviews:

{
        "_id" : ObjectId("53a5753937c2f0ef6dcd9006"),
        "product" : "Super Duper-o-phonic",
        "price" : 11000000000,
        "reviews" : [
                {
                        "user" : "fred",
                        "comment" : "Great!",
                        "rating" : 5
                },
                {
                        "user" : "Tom",
                        "comment" : "Great again!",
                        "rating" : 5
                },
                {
                        "user" : "Tom",
                        "comment" : "I agree with fred somewhat",
                        "rating" : 4
                }
        ]
}

I want to find only those reviews whose rating is 5.

Final query should select product price and two documents from reviews whose rating is 5.

The last query I tried is :

db.testData.find({'reviews':{$elemMatch:{'rating':{$gte:5}}}}).pretty()

It's strange but it doesn't work.

How to do this in mongodb?

2 Answers 2

4

If you only want a single sub-doc from reviews whose rating is 5, you can use the $ positional projection operator to include the first element of reviews that matches your query:

db.test.find({'reviews.rating': 5}, {product: 1, price: 1, 'reviews.$': 1})

If you want all reviews elements with a rating of 5 (instead of just the first) you can use aggregate instead of find:

db.test.aggregate([
    // Only include docs with at least one 5 rating review
    {$match: {'reviews.rating': 5}}, 
    // Duplicate the docs, one per reviews element
    {$unwind: '$reviews'}, 
    // Only include the ones where rating = 5
    {$match: {'reviews.rating': 5}}, 
    // Only include the following fields in the output
    {$project: {product: 1, price: 1, reviews: 1}}])
Sign up to request clarification or add additional context in comments.

2 Comments

I just tried this and it doesn't work if I select two documents from reviews with rating 5. because reviews.$ ensures that only the first matching document is included in result.
@VolodymyrLevytskyi Use the aggregate approach if you want to include all rating 5 reviews instead of just the first one.
0

Take a look up here: MongoDB - how to query for a nested item inside a collection?

Just in case you thought about this: If you try to accomplish this with $elemMatchit will jsut return the first matching review. http://docs.mongodb.org/manual/reference/operator/projection/elemMatch/

1 Comment

I tried $elemMatch and it doesn't work. Can you post a query?

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.