Optimize search SQL query (I hope :p)

This commit is contained in:
Chocobozzz 2018-07-27 15:20:10 +02:00
parent a3c1738eea
commit dbfd3e9bfe
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
2 changed files with 17 additions and 29 deletions

View File

@ -51,17 +51,6 @@ function createSimilarityAttribute (col: string, value: string) {
) )
} }
function createSearchTrigramQuery (col: string, value: string) {
return {
[ Sequelize.Op.or ]: [
// FIXME: use word_similarity instead of just similarity?
Sequelize.where(searchTrigramNormalizeCol(col), ' % ', searchTrigramNormalizeValue(value)),
Sequelize.where(searchTrigramNormalizeCol(col), ' LIKE ', searchTrigramNormalizeValue(`%${value}%`))
]
}
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
export { export {
@ -69,8 +58,7 @@ export {
getSortOnModel, getSortOnModel,
createSimilarityAttribute, createSimilarityAttribute,
throwIfNotValid, throwIfNotValid,
buildTrigramSearchIndex, buildTrigramSearchIndex
createSearchTrigramQuery
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -83,7 +83,7 @@ import { AccountVideoRateModel } from '../account/account-video-rate'
import { ActorModel } from '../activitypub/actor' import { ActorModel } from '../activitypub/actor'
import { AvatarModel } from '../avatar/avatar' import { AvatarModel } from '../avatar/avatar'
import { ServerModel } from '../server/server' import { ServerModel } from '../server/server'
import { buildTrigramSearchIndex, createSearchTrigramQuery, createSimilarityAttribute, getSort, throwIfNotValid } from '../utils' import { buildTrigramSearchIndex, createSimilarityAttribute, getSort, throwIfNotValid } from '../utils'
import { TagModel } from './tag' import { TagModel } from './tag'
import { VideoAbuseModel } from './video-abuse' import { VideoAbuseModel } from './video-abuse'
import { VideoChannelModel } from './video-channel' import { VideoChannelModel } from './video-channel'
@ -883,24 +883,24 @@ export class VideoModel extends Model<VideoModel> {
} }
const attributesInclude = [] const attributesInclude = []
const escapedSearch = VideoModel.sequelize.escape(options.search)
const escapedLikeSearch = VideoModel.sequelize.escape('%' + options.search + '%')
if (options.search) { if (options.search) {
whereAnd.push( whereAnd.push(
{ {
[ Sequelize.Op.or ]: [ id: {
createSearchTrigramQuery('VideoModel.name', options.search), [ Sequelize.Op.in ]: Sequelize.literal(
'(' +
{ 'SELECT "video"."id" FROM "video" WHERE ' +
id: { 'lower(immutable_unaccent("video"."name")) % lower(immutable_unaccent(' + escapedSearch + ')) OR ' +
[ Sequelize.Op.in ]: Sequelize.literal( 'lower(immutable_unaccent("video"."name")) LIKE lower(immutable_unaccent(' + escapedLikeSearch + '))' +
'(' + 'UNION ALL ' +
'SELECT "video"."id" FROM "video" LEFT JOIN "videoTag" ON "videoTag"."videoId" = "video"."id" ' + 'SELECT "video"."id" FROM "video" LEFT JOIN "videoTag" ON "videoTag"."videoId" = "video"."id" ' +
'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' + 'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' +
'WHERE "tag"."name" = ' + VideoModel.sequelize.escape(options.search) + 'WHERE "tag"."name" = ' + escapedSearch +
')' ')'
) )
} }
}
]
} }
) )