Многоязычная локализация Mongoose fetch

Я использую nodejs с mongoose (mongodb), и я хочу отфильтровать выбранный язык внутри массива вложенных документов.

Схема пользователя:

var localUserSchema = new mongoose.Schema({
firstName: {
    type: String
},
moreInformation: {
    experience: {
        type: Number
    },
    specializations: [{
        ...
        sports:[{
        type: Schema.Types.ObjectId, 
        ref: 'sport'
        }]
    }]
});

Данные пользователя:

    [{
    "_id": {
        "$oid": "5fc6a379b1d5ff2c42a9a536"
    },
    "moreInformation": {
        "experience" : 2,
        "specializations": [{
            "sports": [{
                "$oid": "5fc6aa91b1db6cd15702241c"
            }, {
                "$oid": "5fcb741e786f0703646befe2"
            }]
        }]
    }
    }]

Спортивная схема:

var sportSchema = new Schema({ 
    name: {
       en: {
           type: String
       },
       it: {
           type: String
       }
   },  
   icon: {
       type: Schema.Types.ObjectId, ref: 'file'
   }
}); 

Спортивные данные:

[{
      "_id": {
        "$oid": "5fc6aa91b1db6cd15702241c"
      },
      "name": {
        "en": "Football",
        "it": "Calcio"
      },
      "icon": {
        "$oid": "5fc9598a0955177dee8a3bc4"
      }
    },{
      "_id": {
        "$oid": "5fcb741e786f0703646befe2"
      },
      "name": {
        "en": "Swimming",
        "it": "Nuoto"
      },
      "icon": {
        "$oid": "5fc9598a0955177dee8a3bc5"
      }
    }

Я хочу, чтобы все пользователи присоединялись к спорту по идентификатору спорта, но отфильтровывались по ключу языка, как показано ниже, и заменяли языки названия спорта на имя, выбранное без ключа языка.

Итак, если бы я хотел выбрать и отфильтровать английский язык «en», я бы хотел получить такой результат:

[
{
    "_id": "5fc6a379b1d5ff2c42a9a536",
    "moreInformation": {
        "specializations": [{
            ...
            "sports": [
                {
                    "_id": "5fc6aa91b1db6cd15702241c",
                    "name": "Football",
                    "icon": "5fc9598a0955177dee8a3bc4"
                },
                {
                    "_id": "5fcb741e786f0703646befe2",
                    "name": "Swimming",
                    "icon": "5fc9598a0955177dee8a3bc5"
              }]
        }]
        }
    }
}

Как я могу это сделать?

JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Раскрытие чувствительных данных
Раскрытие чувствительных данных
Все внешние компоненты, рассмотренные здесь до сих пор, взаимодействуют с клиентской стороной. Однако, если они подвергаются атаке, они не...
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Руководство ChatGPT по продаже мини JS-файлов
Руководство ChatGPT по продаже мини JS-файлов
JS-файл - это файл, содержащий код JavaScript. JavaScript - это язык программирования, который в основном используется для добавления интерактивности...
0
0
358
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам нужно будет использовать методы агрегации , такие как $unwind , $lookup , $group и, наконец, $project.

Они определяют последовательность шагов, чтобы помочь вам получить ваши данные, как вы ожидаете

Чтобы получить ответ, который вы хотите, взгляните на следующий код и работающий пример здесь

Ps: я предлагаю вам изучить пример на игровой площадке mongo (ссылка выше) и разделить конвейеры агрегации, чтобы лучше понять процесс.

db.users.aggregate([
  {
    // move specializations array to separated objects
    "$unwind": "$moreInformation.specializations" 
  },
  {
    // move specialization.sports to separated objects
    "$unwind": "$moreInformation.specializations.sports"
  },
  {
    // search into sports collection based on the temporary "sports" attribute
    $lookup: {
      from: "sports",
      localField: "moreInformation.specializations.sports",
      foreignField: "_id",
      as: "fullSport"
    }
  },
  {
    // as the lookup resolves an array of a single result we move it to be an object
    "$unwind": "$fullSport"
  },
  {
    // here we select only the attributes that we need and the selected language
    "$project": {
      "moreInformation.experience": 1,
      "moreInformation.specializations.sports._id": "$fullSport._id",
      "moreInformation.specializations.sports.icon": "$fullSport.icon",
      "moreInformation.specializations.sports.name": "$fullSport.name.en"
    }
  },
  {
    // then we group it to make the separated objects an array again
    "$group": {
      "_id": "$_id",
      // we group by the $_id and move it to temporary "sports" attribute
      "sports": {
        $push: "$moreInformation.specializations.sports"
      },
      "moreInformation": {
        $first: "$moreInformation"
      }
    }
  },
  {
    $project: {
      "moreInformation.experience": 1,
      // move back the temporary "sports" attribute to its previous path
      "moreInformation.specializations.sports": "$sports"
    }
  }
])

Другие вопросы по теме