Объединить документы Mongo после нескольких поисков в одной агрегации - PullRequest
0 голосов
/ 25 декабря 2018

Я застрял, пытаясь объединить результаты моего документа.Вот мой запрос и данные

{"_id":"5c21ab13d03013b384f0de26",
"roles":["5c21ab31d497a61195ce224c","5c21ab4ad497a6f348ce224d","5c21ab5cd497a644b6ce224e"],
"agency":"5b4ab7afd6ca361cb38d6a60","agents":["5b4ab5e897b24f1c4c8e3de3"]}

Вот запрос

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

Как видите, запись в коллекции проектов имеет два массива, которые были развернуты перед поиском на каждомвыполняется запись, а затем выполняется окончательный поиск в поле «агентство».

Однако, когда я получаю результаты этого запроса, я получаю количество документов, равное количеству ролей.Например, проект, который я собираю, имеет 3 роли и 1 агента.Итак, я возвращаю массив из 3 объектов, по одному для каждой роли, а не один документ с массивом ролей, содержащим все три роли.Также существует вероятность того, что массив агентов может иметь более одного значения.

Итак, потеряно ...

1 Ответ

0 голосов
/ 25 декабря 2018

Вам не нужно запускать $unwind до $ lookup .Раздел localField гласит:

Если ваш localField является массивом, вы можете добавить этап $ unwind в ваш конвейер.В противном случае условие равенства между localField и foreignField является foreignField: {$ in: [localField.elem1, localField.elem2, ...]}

Так что в основном, если вы не запускаете $unwind например, на roles, тогда вместо документа на роль вы получите массив roles в виде ObjectIds, замененный массивом объектов из этой второй коллекции.

Так что вы можете попробовать следующую агрегацию:

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"
        }
    }
])
...