Дополнительное поле поиска агрегации MongoDB из localField для получения результата - PullRequest
0 голосов
/ 28 мая 2020

У меня есть следующие коллекции в MongoDB ( mongoplayground ) [characters, guilds]

Я хочу создать $lookup, который добавит поле rank в результирующий документ, вот так:

    "members_t": [
      {
        "_id": ObjectId("5a934e000102030405000000"),
        "level": 20,
        "name": "test1",
        "rank": 1
      },
      {
        "_id": ObjectId("5a934e000102030405000001"),
        "level": 40,
        "name": "test2",
        "rank": 2
      }
    ]

старый $lookup синтаксис не может мне с этим помочь, но следующий запрос с новым синтаксисом возвращает мне пустой массив в поле tested (даже без стадии $addFields):

  {
    $lookup: {
      from: "characters",
      let: {
        members_name: "$members.name",
        rank: "$members.rank"
      },
      pipeline: [
        {
          $match: {
            name: "$$members_name"
          }
        }
      ],
      as: "tested"
    }
  }

Итак, есть ли возможность добавить дополнительное поле после стадии $lookup или нет?

(Mon go -v 4.2. 3, поэтому проблема не связана с поддержкой нового синтаксиса)

1 Ответ

1 голос
/ 28 мая 2020

Вы были почти близки к решению. Поскольку members является массивом, вам нужно передать его через $lookup, а затем условно присоединить к нему для каждого символа с помощью $reduce (вы также можете сделать это с $filter, но тогда нам потребуются дополнительные этапы).

Примечание: Объяснение почему нам нужно использовать $expr внутри $lookup конвейера.

Попробуйте это:

db.guilds.aggregate([
  {
    $lookup: {
      from: "characters",
      let: {
        members: "$members"
      },
      pipeline: [
        {
          $match: {
            $expr: {
              $in: [
                "$name",
                "$$members.name"
              ]
            }
          }
        },
        {
          $addFields: {
            rank: {
              $reduce: {
                input: "$$members",
                initialValue: null,
                in: {
                  $cond: [
                    {
                      $eq: [
                        "$$this.name",
                        "$name"
                      ]
                    },
                    "$$this.rank",
                    "$$value"
                  ]
                }
              }
            }
          }
        }
      ],
      as: "members_t"
    }
  }
])

MongoPlayground

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