Reputation: 545
I have documents containing multilingual data. A simplified version looks like:
{
languages: [
"en",
"fr"
],
title: {
en: "Potato Gratin",
fr: "Gratin de pomme de terre"
},
}
Important parts are:
title
contains translations in the shape <lang> : <text>
languages
contains the list of supported languages, the fist one being the default language.What I would like to do is querying that document for a specific language and either
title
object by the correct translation if the language is supportedtitle
object by the default translation if the language is notI-e querying the above document in french should return {"title": "Gratin de pomme de terre"}
and if queried in chinese, it should return {"title": "Potato Gratin"}
I have a playground setup: https://mongoplayground.net/p/CP0Z20dTpgy. I have it so that it sets a lang
property that the output should be in. I would then like to have a stage that looks like "$set": {"title": "$title.$lang"}
but it complains that a field path component should not start with $
, which I am guessing means that mongo does not support dynamic field paths ?
Any idea on how to achieve something like that?
Some notes:
Upvotes: 1
Views: 1019
Reputation: 4343
You have to transform your object to an array with $objectToArray, filter this array and get element 0 of it. Then you can transform back you value.
db.collection.aggregate([
{
"$match": {
"_id": BinData(0, "3BByrilZQ2GTdlXG0nrGXw=="),
},
},
{
"$set": {
"lang": {
"$cond": [
{
"$in": [
"zh",
"$languages"
]
},
"zh",
{
"$first": "$languages"
}
]
}
}
},
{
$addFields: {
title: {
"$arrayElemAt": [
{
"$filter": {
"input": {
"$objectToArray": "$title"
},
"as": "title",
"cond": {
$eq: [
"$$title.k",
"$lang"
]
}
}
},
0
]
}
}
},
{
$addFields: {
title: "$title.v"
}
}
])
Of course, you have to pass your 'zh' as parameter in your code, on both places.
Upvotes: 2