Удалить поле из встроенного проекционного документа после поиска - PullRequest
0 голосов
/ 05 января 2019

У меня есть следующий агрегатный запрос Монго:

    return db.collection('projects').aggregate([
  {
    $match: {
      agents: ObjectId(agent)
    }
  },
  {
    $lookup: {
      from: "agents",
      localField: "agents",
      foreignField: "_id",
      as: "agents"
    }
  },
  {
    $lookup: {
      from: "roles",
      localField: "roles",
      foreignField: "_id",
      as: "roles"
    }
  },
  {
    $lookup: {
      from: "agencies",
      localField: "agency",
      foreignField: "_id",
      as: "agency"
    }
  },
  {
    $lookup: {
      from: "resources",
      localField: "roles.applicants",
      foreignField: "_id",
      as: "roles.applicants"
    }
  }
])

Работает как надо, встраивая нужные документы. Тем не менее, поле «password_hash» отображается для каждого кандидата. Я хочу удалить это поле. Если я попытаюсь спроецировать и установить roles.applicants.password_hash: 0, я фактически получу всего заявителя без хэша пароля, но остальные поля roles больше не будут там. Итак, я получаю что-то похожее на:

roles: {
 applicants: {
  name: "Josh"
 }
}

Это должно быть

roles: {
 title: "Super Hero",
 applicants: {
  name: "Josh"
 }
}

1 Ответ

0 голосов
/ 05 января 2019

Я понял это. Вот как я это сделал. Во-первых, в проекции не было проблемы с тем, почему в документе ролей отсутствовали поля. Это был поиск.

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

 {
    $lookup: {
      from: "roles",
      let: { "roles": "$roles" },
      pipeline: [
        { $match: { $expr: { $in: [ "$_id", "$$roles" ] } } },
        {
          $lookup: {
            from: "resources",
            let: { "applicants": "$applicants" },
            pipeline: [
              { $match: { $expr: { $in: [ "$_id", "$$applicants" ] } } },
              {
                $project: {
                  first_name: 1
                }
              }
            ],
            as: "applicants"
          }
        }
      ],
      as: "roles"
    }
  }

Весь агрегат выглядит так

return db.collection('projects').aggregate([
  {
    $match: {
      agents: ObjectId(agent)
    }
  },
  {
    $lookup: {
      from: "agents",
      localField: "agents",
      foreignField: "_id",
      as: "agents"
    }
  },
  {
    $lookup: {
      from: "agencies",
      localField: "agency",
      foreignField: "_id",
      as: "agency"
    }
  },      
  {
    $lookup: {
      from: "roles",
      let: { "roles": "$roles" },
      pipeline: [
        { $match: { $expr: { $in: [ "$_id", "$$roles" ] } } },
        {
          $lookup: {
            from: "resources",
            let: { "applicants": "$applicants" },
            pipeline: [
              { $match: { $expr: { $in: [ "$_id", "$$applicants" ] } } },
              {
                $project: {
                  first_name: 1
                }
              }
            ],
            as: "applicants"
          }
        }
      ],
      as: "roles"
    }
  }
])
...