Преобразование оператора подзапроса PostgreSQL в запрос Sequelize - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть две таблицы: Пользователь и Публикации. Пользователь имеет разные роли, такие как администратор и подписчик. Существует ассоциация User.hasMany(Publication) и Publication.belongsTo(User), позволяющая администратору создавать публикации, связанные с их userId.

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

Я хочу создать запрос для подписчика, чтобы получить доступ к индексу их доступных публикаций и соответствующим столбцам для него. Моя проблема не в том, чтобы сделать это в Sequelize для моего узла / экспресс-приложения. Вот как я могу получить то, что я хочу в SQL:

SELECT * 
FROM "Publications"
WHERE "id" IN (
  SELECT unnest("subscribedPublications") as "subscribedPublications"
  FROM "Users"
  WHERE "id"='f3fc2553-699c-49e0-8ad5-5a4692af1473'
);

При этом создается таблица с рядом подробностей для каждой публикации (поскольку я unnest мой массив здесь).

Обратите внимание, что для этого я использую определенный userId в своем подзапросе. Я передам req.params.id в своем маршруте для авторизованного подписчика, чтобы я мог использовать его для получения их коллекции subscribedPublications.

До сих пор я только успешно получал публикации только этого конкретного пользователя по телефону:

return User.findById(id, {
  attributes: ['subscribedPublications']
})

Однако это не дает мне подробную информацию о публикациях - только идентификаторы публикаций.

Я тоже попробовал, но безуспешно:

const Sequelize = require("sequelize");
const sequelize = require("../../src/db/models/index").sequelize;
const Op = Sequelize.Op;
const Publication = require("./models").Publication;
const User = require("./models").User;

return Publication.findAll({
  where: {
    id: {
      [Op.in]: sequelize.query(
        '(SELECT unnest("subscribedPublications") as "subscribedPublications" FROM "Users" WHERE "id" = :id)',
        {replacements: {id: id}},
        { type: Sequelize.QueryTypes.SELECT}
      )
    }
  }
})
.then((publications) => {
  console.log(publications);
})
.catch((err) => {
  console.log(err);
})

Я получаю пустое значение [] за результат.

Другие примечания:

  • Я должен был включить приведенные выше определения сиквелизов, потому что я был иначе получаю ошибки.
  • ради простоты, я только что добавил console.log для моего Обещания.
  • Я не знаю, вызывает ли тип Array дальнейшие осложнения.

TL; DR

Необходимо создать запрос Sequelize, который дает результаты, которые я могу получить из оператора подзапроса SQL. Столбец / поле, которое мне нужно, имеет тип Array в PostgreSQL - не знаю, нужно ли это отображать в Sequelize.

1 Ответ

0 голосов
/ 05 сентября 2018

Мне удалось выяснить это с помощью sequelize.literal вместо sequelize.query +, позволяющего передать мой параметр id благодаря конкатенации строк:

return Publication.findAll({
  attributes: ['id', 'title', 'fileLocation', 'tickerSymbol', 'recommendedPrice', 'createdAt', 'updatedAt'],
  where: {
    id: {
      [Op.in]: sequelize.literal(
        '(SELECT unnest("subscribedPublications") as "subscribedPublications" FROM "Users" WHERE "id" ='+ '\'' + id + '\')'
      )
    }
  }
})
.then((publications) => {
  console.log(publications);
})
.catch((err) => {
  console.log(err);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...