Reputation: 346
I'm not able to describe my thought precisely in words, so here's an example:
[
{
'description': 'fruits',
'examples': [
{
'name': 'Apple',
'color': ['red', 'green']
},
{
'name': 'Banana',
'color': 'yellow'
}
]
},
{
'description': 'vegetables',
'examples': [
{
'name': 'Tomato',
'color': 'red'
},
{
'name': 'Carrot',
'color': 'orange'
}
]
},
{
'description': 'Wweets',
'examples': [
{
'name': 'Chocolate',
'color': ['brown', 'black', 'white']
},
{
'name': 'Candy',
'color': 'various'
}
]
}
]
Let's go step by step:
If I want to see all food categories, I query by the following command
db.food.find()
I want to see the vegetables
db.food.find({ 'description': 'vegetables' })
Now let's say I forgot how a Carrot looks like (lol). What do I do? I tried the following (Native node.js MongoDB driver):
collection.find({'examples.name': 'Carrot'}, function(err, example){
console.log(example)
// It still returns me the whole object!
});
As a result I expected MongoDB to return the next highest instance of the object. For example I wanted to do this.
console.log(example.color)
// 'orange'
Do you have any idea? I'm new to document oriented DBs :/
Upvotes: 2
Views: 4273
Reputation: 42352
When you store a bunch of objects in a single document you will (by default) get back the entire document. [*]
When one of the fields of the document is an array, you will get back the full array if the item you are trying to match is found in the array.
Don't fall for the temptation to cram everything into a single document if you will normally be getting back only a subset of those things.
You have an alternative available:
You can store a collection of foods where every food has a field "type" which is "fruit" or "vegetable" or "...". You can still query for all foods, or just foods of type "fruit" or just food with name "carrot", etc.
Arrays are great for lists of attributes of a particular object/document, they are not as good when you cram documents into them that you then want to get back as first-class objects.
[*] there is a way to project and get only a subset of the fields, but you will still get back entire fields.
Upvotes: 2