I have a collection of a few thousand characters. Each character has eight localized fields and nine different supported languages. Below is an example of the schema I am using populated with sample data (just with a smaller document).
db.characters.insertMany([
{
"key": 123,
"attack": 1337,
"numberField3": 30
"translations": {
"en": {
"name": "Englishh name"
"description": "English description"
},
"es": {
"name": "Spanish name"
"description": "Spanish description"
}
}
},...
])
How can I make a query that returns a document containing the non-localized fields and the localized fields from the specified language?
pseudo-query: db.characteres.find({"key":123}).addAll("translations.en")
would return:
{
"key": 123,
"attack": 1337,
"numberField3": 30
"name": "Englishh name"
"description": "English description"
}
Thank you for looking at this. First time mongodb user and data-modeling noob here
UPDATE
I just found an example (thanks ChatGPT) that would do what I need using $project. Is there a more performant way of doing this? or possibly shorter solution (each document has 8 localized fields I will have to add into $project); can I project the fields I want then add_all fields from translation.en to the root level? that would be a more generalized way to achieve what I am trying to do with localization in a query
db.characters.aggregate([
{
$match: {
"key": 123
}
},
{
$project: {
"_id": 0,
"key": 1,
"attack": 1,
"numberField3": 1,
"name": "$translations.en.name",
"description": "$translations.en.description"
}
}
])
UPDATE #2
Upon further prodding ChatGPT gave me this. Can anyone confirm this is a proper pipeline or know of a better way to do this? I can not currently connect to the db due to other reasons
db.characters.aggregate([
{
$match: {
"key": 123
}
},
{
$replaceRoot: {
newRoot: {
$mergeObjects: ["$$ROOT", "$translations.en"]
}
}
},
{
$project: {
"translations": 0
}
}
])
2
Answers
The
$project
in your pipeline won’t produce the result you expect: it will just return the_id
of the document, that’s it. You have to use$unset
for that.A potentially slightly faster aggregation can be achieved using
$addFields
. This would merge your last two pipeline steps (not verified the syntax, but should give a hint):If you want a different name: