Fix discover home page shelf query, add indexes for libraryItems and mediaProgresses table

This commit is contained in:
advplyr 2023-08-09 17:48:31 -05:00
parent 33e04d0cbb
commit 8c9fc3ddb5
4 changed files with 56 additions and 19 deletions

View File

@ -448,7 +448,10 @@ module.exports = (sequelize) => {
* @returns {object} { libraryItems:oldLibraryItem[], count:number } * @returns {object} { libraryItems:oldLibraryItem[], count:number }
*/ */
static async getByFilterAndSort(library, user, options) { static async getByFilterAndSort(library, user, options) {
let start = Date.now()
const { libraryItems, count } = await libraryFilters.getFilteredLibraryItems(library, user, options) const { libraryItems, count } = await libraryFilters.getFilteredLibraryItems(library, user, options)
Logger.debug(`Loaded ${libraryItems.length} of ${count} items for libary page in ${((Date.now() - start) / 1000).toFixed(2)}s`)
return { return {
libraryItems: libraryItems.map(li => { libraryItems: libraryItems.map(li => {
const oldLibraryItem = this.getOldLibraryItem(li).toJSONMinified() const oldLibraryItem = this.getOldLibraryItem(li).toJSONMinified()
@ -692,7 +695,15 @@ module.exports = (sequelize) => {
extraData: DataTypes.JSON extraData: DataTypes.JSON
}, { }, {
sequelize, sequelize,
modelName: 'libraryItem' modelName: 'libraryItem',
indexes: [
{
fields: ['createdAt']
},
{
fields: ['mediaId']
}
]
}) })
const { library, libraryFolder, book, podcast } = sequelize.models const { library, libraryFolder, book, podcast } = sequelize.models

View File

@ -90,7 +90,12 @@ module.exports = (sequelize) => {
extraData: DataTypes.JSON extraData: DataTypes.JSON
}, { }, {
sequelize, sequelize,
modelName: 'mediaProgress' modelName: 'mediaProgress',
indexes: [
{
fields: ['updatedAt']
}
]
}) })
const { book, podcastEpisode, user } = sequelize.models const { book, podcastEpisode, user } = sequelize.models

View File

@ -1620,11 +1620,12 @@ async function migrationPatch2BookSeries(ctx, offset = 0) {
*/ */
module.exports.migrationPatch2 = async (ctx) => { module.exports.migrationPatch2 = async (ctx) => {
const queryInterface = ctx.sequelize.getQueryInterface() const queryInterface = ctx.sequelize.getQueryInterface()
const libraryItemsIndexes = await queryInterface.showIndex('libraryItems')
const feedTableDescription = await queryInterface.describeTable('feeds') const feedTableDescription = await queryInterface.describeTable('feeds')
const authorsTableDescription = await queryInterface.describeTable('authors') const authorsTableDescription = await queryInterface.describeTable('authors')
const bookAuthorsTableDescription = await queryInterface.describeTable('bookAuthors') const bookAuthorsTableDescription = await queryInterface.describeTable('bookAuthors')
if (feedTableDescription?.coverPath && authorsTableDescription?.lastFirst && bookAuthorsTableDescription?.createdAt) { if (feedTableDescription?.coverPath && authorsTableDescription?.lastFirst && bookAuthorsTableDescription?.createdAt && libraryItemsIndexes.some(lii => lii.name === 'library_items_created_at')) {
Logger.info(`[dbMigration] Migration patch 2.3.3+ - columns already on model`) Logger.info(`[dbMigration] Migration patch 2.3.3+ - columns already on model`)
return false return false
} }
@ -1633,13 +1634,29 @@ module.exports.migrationPatch2 = async (ctx) => {
try { try {
await queryInterface.sequelize.transaction(t => { await queryInterface.sequelize.transaction(t => {
const queries = [ const queries = [
queryInterface.addIndex('libraryItems', {
fields: ['mediaId'],
transaction: t
}),
queryInterface.addIndex('libraryItems', {
fields: ['createdAt'],
transaction: t
}),
queryInterface.addIndex('mediaProgresses', {
fields: ['updatedAt'],
transaction: t
})
]
if (!bookAuthorsTableDescription?.createdAt) {
queries.push(...[
queryInterface.addColumn('bookAuthors', 'createdAt', { queryInterface.addColumn('bookAuthors', 'createdAt', {
type: DataTypes.DATE type: DataTypes.DATE
}, { transaction: t }), }, { transaction: t }),
queryInterface.addColumn('bookSeries', 'createdAt', { queryInterface.addColumn('bookSeries', 'createdAt', {
type: DataTypes.DATE type: DataTypes.DATE
}, { transaction: t }), }, { transaction: t }),
] ])
}
if (!authorsTableDescription?.lastFirst) { if (!authorsTableDescription?.lastFirst) {
queries.push(...[ queries.push(...[
queryInterface.addColumn('authors', 'lastFirst', { queryInterface.addColumn('authors', 'lastFirst', {
@ -1691,11 +1708,13 @@ module.exports.migrationPatch2 = async (ctx) => {
await migrationPatch2Series(ctx, 0) await migrationPatch2Series(ctx, 0)
} }
if (!bookAuthorsTableDescription?.createdAt) {
// Patch bookAuthors createdAt column // Patch bookAuthors createdAt column
await migrationPatch2BookAuthors(ctx, 0) await migrationPatch2BookAuthors(ctx, 0)
// Patch bookSeries createdAt column // Patch bookSeries createdAt column
await migrationPatch2BookSeries(ctx, 0) await migrationPatch2BookSeries(ctx, 0)
}
Logger.info(`[dbMigration] Migration patch 2.3.3+ finished`) Logger.info(`[dbMigration] Migration patch 2.3.3+ finished`)
return true return true

View File

@ -261,7 +261,7 @@ module.exports = {
} }
} else if (sortBy === 'sequence') { } else if (sortBy === 'sequence') {
const nullDir = sortDesc ? 'DESC NULLS FIRST' : 'ASC NULLS LAST' const nullDir = sortDesc ? 'DESC NULLS FIRST' : 'ASC NULLS LAST'
return [[Sequelize.literal(`CAST(\`series.bookSeries.sequence\` AS INTEGER) ${nullDir}`)]] return [[Sequelize.literal(`CAST(\`series.bookSeries.sequence\` AS FLOAT) ${nullDir}`)]]
} else if (sortBy === 'progress') { } else if (sortBy === 'progress') {
return [[Sequelize.literal('mediaProgresses.updatedAt'), dir]] return [[Sequelize.literal('mediaProgresses.updatedAt'), dir]]
} }
@ -299,7 +299,7 @@ module.exports = {
} }
], ],
order: [ order: [
Sequelize.literal('CAST(`books.bookSeries.sequence` AS INTEGER) ASC NULLS LAST') Sequelize.literal('CAST(`books.bookSeries.sequence` AS FLOAT) ASC NULLS LAST')
] ]
}) })
const bookSeriesToInclude = [] const bookSeriesToInclude = []
@ -458,7 +458,7 @@ module.exports = {
}) })
if (sortBy !== 'sequence') { if (sortBy !== 'sequence') {
// Secondary sort by sequence // Secondary sort by sequence
sortOrder.push([Sequelize.literal('CAST(`series.bookSeries.sequence` AS INTEGER) ASC NULLS LAST')]) sortOrder.push([Sequelize.literal('CAST(`series.bookSeries.sequence` AS FLOAT) ASC NULLS LAST')])
} }
} else if (filterGroup === 'issues') { } else if (filterGroup === 'issues') {
libraryItemWhere[Sequelize.Op.or] = [ libraryItemWhere[Sequelize.Op.or] = [
@ -670,7 +670,7 @@ module.exports = {
separate: true, separate: true,
subQuery: false, subQuery: false,
order: [ order: [
[Sequelize.literal('CAST(sequence AS INTEGER) ASC NULLS LAST')] [Sequelize.literal('CAST(sequence AS FLOAT) ASC NULLS LAST')]
], ],
where: { where: {
'$book.mediaProgresses.isFinished$': { '$book.mediaProgresses.isFinished$': {
@ -769,11 +769,13 @@ module.exports = {
where: userPermissionBookWhere.bookWhere where: userPermissionBookWhere.bookWhere
}, },
order: [ order: [
[Sequelize.literal('CAST(sequence AS INTEGER) ASC NULLS LAST')] [Sequelize.literal('CAST(sequence AS FLOAT) ASC NULLS LAST')]
], ],
limit: 1 limit: 1
}, },
subQuery: false subQuery: false,
limit,
order: Database.sequelize.random()
}) })
const booksFromSeriesToInclude = seriesNotStarted.map(se => se.bookSeries?.[0]?.bookId).filter(bid => bid) const booksFromSeriesToInclude = seriesNotStarted.map(se => se.bookSeries?.[0]?.bookId).filter(bid => bid)