Reputation: 2101
After reading all online resources that I could think of still unable to think of solution to this one. Basically, I have documents with following data in mongo:
// 1
{
a: {
b: {
languages: {
en: {
text: "en",
type: "secret"
},
de: {
text: "de"
}
}
}
}
}
//2
{
a: {
b: {
languages: {
fr: {
text: "fr"
},
de: {
text: "de",
type: "public"
}
}
}
}
},
this returns me whatever the first document is, it doesn't matter when I change the secret
to whatever:
db.products.findOne({"a.b.languages": {$exists: {$elemMatch: {"type": {$eq: "secret"}}}}}, {"key": 1, "a.b.languages": 1})
What I'm after is all the documents that contain languages of certain type - this field is also optional. How could I construct such a query?
Also if this problem is standard please provide me info so that I could update the question.
Upvotes: 1
Views: 603
Reputation: 49985
The problem you are experiencing here is that there's no array in your documents - you just have nested objects with unknown keys. To query that kind of structure you need to convert those nested documents into an array using $objectToArray operator.
db.col.aggregate([
{
$addFields: {
languages: { $objectToArray: "$a.b.languages" }
}
},
{
$match: { "languages.v.type": "secret" }
},
{
$project: { languages: 0 }
}
])
above code will convert a.b.languages
path into an array of keys and values (object with k
and v
fields) so you can query directly referencing languages.v.type
then. $addFields
and $project
are used to generate and then remove temporary field that can be queried.
Upvotes: 2