Reputation: 903
There are two tables: Books
, listing available books, and BorrowedBooks
, listing books that are currently borrowed. I want to retrieve only books that are currently available (not borrowed), providing pagination and total number count.
I would use the method findAndCountAll
provided by Sequelize, which is really easy to use and does most of the works, but it does not work properly. I have tried the following piece of code, using the findAll
method, which works correctly.
Books.findAll({
where: { '$BorrowedBooks.bookId$': null },
include: [BorrowedBooks]
}).then(...).catch(...);
Then I changed the method to findAndCountAll
, in order to obtain the total count of elements and also providing pagination.
Books.findAndCountAll({
where: { '$BorrowedBooks.bookId$': null },
include: [BorrowedBooks],
offset: offset,
limit: limit,
distinct: true
}).then(...).catch(...);
This version produces an error Unknown column 'BorrowedBooks.bookId' in 'where clause'
.
EDIT
The generated query with the piece of code that does not work is the following:
SELECT
`books`.*,
`borrowedBooks`.`bookId` AS `borrowedBooks.bookId`,
`borrowedBooks`.`userId` AS `borrowedBooks.userId`,
FROM
(SELECT
`books`.`id`,
`books`.`title`,
`books`.`author`,
`books`.`isbn`
FROM
`books` AS books`
WHERE
(SELECT
`bookId`
FROM
`borrowedBooks`
WHERE
(`borrowedBooks`.`bookId` = `books`.`id`
AND `borrowedBooks`.`bookId` IS NULL)
LIMIT 1) IS NOT NULL
LIMIT 0 , 10) AS `books`
INNER JOIN
`borrowedBooks` ON `books`.`id` = `borrowedBooks`.`bookId`
AND `borrowedBooks`.`bookId` IS NULL;
If I would write down directly the query I would do something like this:
SELECT * FROM `books`
LEFT OUTER JOIN `borrowedBooks` ON `books`.`id` = `borrowedBooks`.`bookId`
WHERE `borrowedBooks`.`bookId` IS NULL
I think that the error is due to the INNER JOIN that Sequelize uses.
Upvotes: 1
Views: 14614
Reputation: 433
Node pagination with sequelize
client needs to provide page and pageSize
Pass distinct: true
into the query and it will work how you want it to. you will have included data as well.
const page = 1
const pageSize = 2
const offset = page * pageSize
const limit = offset + pageSize
return model
.findAll({
attributes: [],
include: [{}],
distinct: true,
limit,
offset
})
.then((tasks) => res.status(200).send(tasks))
.catch((error) => {
console.log(error);
res.status(400).send(error);
});
Upvotes: 1
Reputation: 46481
Correct syntax to use include
Books.findAll({
include: [{
model: BorrowedBooks,
where: {
bookId: null
}
}],
offset: offset,
limit: limit,
distinct: true
}).then(...).catch(...);
Upvotes: 4