0

Mongo version : 3.2.8

My sample json is as below

enter image description here

My query to fetch name equal to apple doesn't work.

db.collection.find( { "products.foods.name": "apple" } )

Instead it fetches all the records, strange?

Neither does the $eq, $lt or $gt work. They result with the entire data.

db.aggregation.find( { "products.foods.min_price": {$eq:10} } )

Thanks in advance.

Neil Lunn
  • 130,590
  • 33
  • 275
  • 280
Some Java Guy
  • 4,530
  • 17
  • 61
  • 97
  • 1
    As others already told you, matching a part of the document returns the complete document unless you take special measures like using the aggregation framework. However, as you seem to regard the food-entries as single records and expect them to be returned individually from that query, my guess is that you have a rather fundamental misunderstanding regarding documents in mongo. The JSON you posted looks like one document to hold it all, which about equals wrtiting all your data in a single row in a relational database. Consider a separate collection for food and individual docs per entry. – mtj Nov 10 '16 at 13:20

4 Answers4

1

If your entire document is in an _id, then if the query matches db.collection.find( { "products.foods.name": "apple" } ) even though it is a document in foods array the entire document will be displayed, so that you are getting other fruits as well.

To Solve this first use $unwind the aggregation pipeline to break the foods array into individual documents and then use $match.

Please refer this post, It is a similar question and I have answered the steps in detail in that post.

Community
  • 1
  • 1
Clement Amarnath
  • 4,779
  • 1
  • 16
  • 29
0

Try with this:

db.test.aggregate([
    {$match: {'products.foods.name': 'apple'}}])

Taken from Retrieve only the queried element in an object array in MongoDB collection

You can try other examples from that post.

Community
  • 1
  • 1
Kumar Sourav
  • 370
  • 2
  • 16
0

Try with this:db.Exercise.aggregate([ {$match: {'products.foods.min_price': 10}}])

Mital Gajjar
  • 234
  • 1
  • 6
0

The solution is to n $unwind both the arrays.

db.foods.aggregate([   
    { $unwind : "$products" },
    { $unwind : "$products.foods" },
    { $match  : { "products.foods.min_price": 10        }}
])
Some Java Guy
  • 4,530
  • 17
  • 61
  • 97