Поиск Mongodb с массивом - PullRequest
       60

Поиск Mongodb с массивом

0 голосов
/ 05 августа 2020

У меня есть две коллекции, первая -

коллекция user_profile

const userProfileSchema = mongoose.Schema({
  
  phone_number: {
    type: String,
    required: false,
  },
  primary_skills: [
    {
      skill_id: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Skill'
      },
      years: Number,
    }
  ]
});

образец данных

{
  "phone_number":"222",
   "primary_skills":[{skill_id:1,years:12},{skill_id:2,years:13}]
}

в primary_skills ключ skill_id сопоставлен с другой коллекцией с именем навыки

набор навыков

const skillSchema = mongoose.Schema({
  name: {
    type: String,
    required: true,
    unique:true,
  },
});

образец данных

[
   {
   id:1,
   name:'php'
   },
  {
   id:2,
   name:'java'
  }
]

Я хочу получить все значения в коллекции user_profile вместе с соответствующим skills именем

ожидаемым результатом:

{
 "phone_number":"222",
 "primary_skills":[{
    name:"php",skill_id:1,years:12
 },{
  name:"java",skill_id:2,years:13}
]
}

Я нашел похожую ветку на свой вопрос Поиск MongoDB, когда внешнее поле массив объектов , но он выполняет противоположное тому, что я хочу

Это тот запрос, который я пробовал

profile.aggregate([{
     $lookup:{
        from:'skills',
        localField:'primary_skills.skill_id',
        foreignField:'_id',
        'as':'primary_skills'
      }
   
}])

Он отлично работает, но не содержит years ключ

1 Ответ

1 голос
/ 05 августа 2020

Вам нужно сделать это с помощью $unwind и $group,

  • $unwind primary_skills, потому что это массив, и нам нужно искать субдокумент мудро
db.user_profile.aggregate([
  {
    $unwind: "$primary_skills"
  },
  • $lookup для присоединения primary_skills, что вы уже сделали
  {
    $lookup: {
      from: "skills",
      localField: "primary_skills.skill_id",
      foreignField: "id",
      as: "primary_skills.name"
    }
  },
  • $unwind primary_skills.name, что мы сохранили результат соединения , его массив, и мы раскручиваем, чтобы сделать объект
  {
    $unwind: {
      path: "$primary_skills.name"
    }
  },
  • $addFields заменить поле name, что у нас есть объект, и нам нужно только имя
  {
    $addFields: {
      "primary_skills.name": "$primary_skills.name.name"
    }
  },
  • $group на _id, потому что у нас есть раскрутка и нам нужно объединить все документы
  {
    $group: {
      _id: "$_id",
      phone_number: {
        $first: "$phone_number"
      },
      primary_skills: {
        $push: "$primary_skills"
      }
    }
  }
])

Площадка: https://mongoplayground.net/p/bDmrOwmASn5

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...