Понимание 'include' при разрешении связи источника с целью в sequelize и apollo-server - PullRequest
0 голосов
/ 23 декабря 2018

Я пишу распознаватель (используя sequelize) для моего сервера apollo и пытаюсь понять, как работает решение этой обратной ассоциации ... Я очень запутался в том, как работает include в моем запросе sequelize.

ассоциации моей модели:

User.hasOne(models.Profile)  <- so the foreign key 'userId' is on the profile table

Profile.belongsTo(models.User) <- foreign key 'userId' still on profile table

моя схема graphql:

type Profile {
  id: ID!
  user: User!
}

мой преобразователь: (Я не могу запросить модель User, используя where: {profileId: profile.id}поскольку внешний ключ profileId не существует в User), поэтому ... я использую include ..

Profile: {
  user: async (profile, _args, { models }) => {
    return await models.User.findOne({
      include: [{
        model: models.Profile,
        where: { id: profile.id } <- this makes zero sense to me.. id is the id of the Profile row? how does this work??
      }]
    })

1 Ответ

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

Используя опцию include, вы нетерпеливо загружаете указанную связанную модель.Из документов :

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

Когда вы include связываете модель, под капотом Sequelize присоединяет оператор соединения к запросу, который она генерирует.По умолчанию это LEFT OUTER JOIN.Это означает, что если вы напишите:

User.findAll({ include: [{ model: Profile }] })

Результирующий запрос найдет всех пользователей.Если у пользователя есть Профиль, соответствующая строка в результате также будет содержать поля профиля.С другой стороны, мы можем заставить соединение быть INNER JOIN, добавив параметр required:

User.findAll({ include: [{ model: Profile, required: true }] })

Поскольку это INNER JOIN, результирующий запрос возвращает only Пользователи, имеющие профиль.

Когда вы добавляете where в include, JOIN автоматически преобразуется в INNER JOIN (если вы явно не установили required в false).Само условие where фактически становится частью оператора ON INNER JOIN.Поэтому, если мы напишем:

User.findAll({ include: [{ model: Profile, where: { id: 'someId' } }] })

, результаты будут включать всех пользователей с профилями и , где идентификатор этого профиля равен someId.where всегда зависит от модели, которую мы включаем, поэтому нет необходимости указывать поле id модели, в котором мы заинтересованы.

И наконец, если использовать findOne вместо findAll, Sequelize просто добавляет LIMIT из 1 к запросу, и метод разрешается к одному экземпляру модели вместо массива.

Полное обсуждение объединений выходит за рамки этого вопроса.Вы можете проверить эти другие вопросы для более подробной информации:

...