Reputation: 155
having a collection(productList) and document like below:
{ "_id":"1",
"product_name" : "Haier 240l",
"version" : "1.0",
"filterInfo" : [
{
"name" : "brand",
"value" : "Haier"
},
{
"name" : "energy_rating",
"value" : "4 Star"
}
]
}
{ "_id":"2",
"product_name" : "Haier 310l",
"version" : "1.0",
"filterInfo" : [
{
"name" : "brand",
"value" : "Haier"
},
{
"name" : "energy_rating",
"value" : "3 Star"
}
]
}
{ "_id":"3",
"product_name" : "Samsung 275l",
"version" : "1.0",
"filterInfo" : [
{
"name" : "brand",
"value" : "Samsung"
},
{
"name" : "energy_rating",
"value" : "3 Star"
}
]
}
{ "_id":"4",
"product_name" : "Lg 254l",
"version" : "1.0",
"filterInfo" : [
{
"name" : "brand",
"value" : "Lg"
},
{
"name" : "energy_rating",
"value" : "3 Star"
}
]
}
I want to fetch all document with (i), brand:Haier and energy_rating:3
And (ii) brand:Haier or brand:Samsung and energy_rating:3
For (i) I tried, using elemMatch below queries:
db.productList.find({filterInfo: { $elemMatch: {'name':{$in:['brand','enery_rating']},'value':{$in:['Samsung','3 Star']}}}})
db.getCollection('productList').find({'filterInfo': {$elemMatch: { 'value':'Samsung', 'value' :'3 Star'} } })
db.getCollection('productList').find({'filterInfo': {$elemMatch: { $and:[ {'name':'brand', 'value' :'Samsung'}, {'name':'energy_rating', 'value':'3 Star' } ]} } })
db.getCollection('productList').find({'filterInfo': {$elemMatch: { 'name':'brand', 'value' :'Samsung', 'name':'energy_rating', 'value':'3 Star'} } })
But none of these is working correctly. I am doing some bascis wrong here (Novice here).
Upvotes: 1
Views: 2782
Reputation: 2261
No need for $elemMatch
in this, I would say.
First Query
db.productList.find({
$and:[
{'filterInfo.value':'Haier'},
{'filterInfo.value':'3 Star'}
]
});
Second Query
db.productList.find({
$and:[
{'filterInfo.value':{
$in:['Haier','Samsung']}
},
{'filterInfo.value':'3 Star'}
]
});
Concentrate more on data structuring in MongoDB for optimized performance.
I don't know your application logic, But is it necessary to keep all those data in an array. I don't see the need of that when you can keep data simple like JSON 1 or if you are specific about filterInfo
key can be designed like JSON 2.
JSON 1
{
"_id" : "1",
"product_name" : "Haier 240l",
"version" : "1.0",
"brand":"Haier",
"energy_rating":"4 Star"
}
JSON 2
{
"_id" : "1",
"product_name" : "Haier 240l",
"version" : "1.0",
"filterInfo": {
"brand":"Haier",
"energy_rating":"4 Star"
}
}
Upvotes: 0
Reputation: 75984
First Query
db.productList.find({
"$and":[
{"filterInfo":{"$elemMatch":{"name":"brand","value":"Haier"}}},
{"filterInfo":{"$elemMatch":{"name":"energy_rating","value":"3 Star"}}}
]
})
You can simplify the first query using $all with $elemMatch
to perform queries on arrays.
db.productList.find({
"filterInfo":{
"$all":[
{"$elemMatch":{"name":"brand","value":"Haier"}},
{"$elemMatch":{"name":"energy_rating","value":"3 Star"}}
]
}
})
Second Query
db.productList.find({
"$and":[
{"$or":[
{"filterInfo":{"$elemMatch":{"name":"brand","value":"Samsung"}}},
{"filterInfo":{"$elemMatch":{"name":"brand","value":"Haier"}}}
]},
{"filterInfo":{"$elemMatch":{"name":"energy_rating","value":"3 Star"}}}
]
})
Upvotes: 2