Refactored manticore SQL query to use scenes_stashed as primary table.

This commit is contained in:
2024-03-17 03:03:36 +01:00
parent 911461784b
commit 929de64aa0
6 changed files with 69 additions and 34 deletions

View File

@@ -359,7 +359,7 @@ async function queryManticoreJson(filters, options, _reqUser) {
}
async function queryManticoreSql(filters, options, _reqUser) {
const aggSize = 10 || config.database.manticore.maxAggregateSize;
const aggSize = config.database.manticore.maxAggregateSize;
const sqlQuery = knexManticore.raw(`
:query:
@@ -379,13 +379,27 @@ async function queryManticoreSql(filters, options, _reqUser) {
:tagsFacet:
:channelsFacet:
`, {
query: knexManticore('scenes')
.select(knex.raw('*, weight() as _score'))
query: knexManticore(filters.stashId ? 'scenes_stashed' : 'scenes')
.modify((builder) => {
if (filters.stashId) {
builder.select(knex.raw(`
scenes.id as id,
scenes.title as title,
scenes.actor_ids as actor_ids,
scenes.tag_ids as tag_ids,
scenes.channel_id as channel_id,
scenes.network_id as network_id,
scenes.effective_date as effective_date,
scenes.created_at,
created_at as stashed_at,
weight() as _score
`));
builder
.innerJoin('scenes_stashed', 'scenes.id', 'scenes_stashed.scene_id')
.where('scenes_stashed.stash_id', filters.stashId);
.innerJoin('scenes', 'scenes.id', 'scenes_stashed.scene_id')
.where('stash_id', filters.stashId);
} else {
builder.select(knex.raw('*, weight() as _score'));
}
if (filters.query) {
@@ -411,57 +425,67 @@ async function queryManticoreSql(filters, options, _reqUser) {
if (!filters.scope || filters.scope === 'latest') {
builder
.where('effective_date', '<=', Math.round(Date.now() / 1000))
.orderBy('effective_date', 'desc');
.orderBy('scenes.effective_date', 'desc'); // can't seem to use alias if it matches column-name? behavior not fully understand, but this works
} else if (filters.scope === 'upcoming') {
builder
.where('effective_date', '>', Math.round(Date.now() / 1000))
.orderBy('effective_date', 'asc');
.orderBy('scenes.effective_date', 'asc');
} else if (filters.scope === 'new') {
builder.orderBy([
{ column: 'created_at', order: 'desc' },
{ column: 'effective_date', order: 'asc' },
{ column: 'scenes.created_at', order: 'desc' },
{ column: 'scenes.effective_date', order: 'asc' },
]);
} else if (filters.scope === 'likes') {
builder.orderBy([
{ column: 'stashed', order: 'desc' },
{ column: 'effective_date', order: 'desc' },
{ column: 'scenes.stashed', order: 'desc' },
{ column: 'scenes.effective_date', order: 'desc' },
]);
} else if (filters.scope === 'results') {
builder.orderBy([
{ column: '_score', order: 'desc' },
{ column: 'effective_date', order: 'desc' },
{ column: 'scenes._score', order: 'desc' },
{ column: 'scenes.effective_date', order: 'desc' },
]);
} else if (filters.scope === 'stashed' && filters.stashId) {
builder.orderBy([
{ column: 'stashed_at', order: 'desc' },
{ column: 'scenes.effective_date', order: 'desc' },
]);
} else {
builder.orderBy('effective_date', 'desc');
builder.orderBy('scenes.effective_date', 'desc');
}
})
.limit(options.limit)
.toString(),
// option threads=1 fixes actors, but drastically slows down performance, wait for fix
actorsFacet: options.aggregateActors ? knex.raw('facet actor_ids order by count(*) desc limit ?', [aggSize]) : null,
tagsFacet: options.aggregateTags ? knex.raw('facet tag_ids order by count(*) desc limit ?', [aggSize]) : null,
channelsFacet: options.aggregateChannels ? knex.raw('facet channel_id order by count(*) desc limit ?', [aggSize]) : null,
actorsFacet: options.aggregateActors ? knex.raw('facet scenes.actor_ids order by count(*) desc limit ?', [aggSize]) : null,
tagsFacet: options.aggregateTags ? knex.raw('facet scenes.tag_ids order by count(*) desc limit ?', [aggSize]) : null,
channelsFacet: options.aggregateChannels ? knex.raw('facet scenes.channel_id order by count(*) desc limit ?', [aggSize]) : null,
maxMatches: config.database.manticore.maxMatches,
maxQueryTime: config.database.manticore.maxQueryTime,
}).toString();
console.log(sqlQuery);
// manticore does not seem to accept table.column syntax if 'table' is primary (yet), crude work-around
const curatedSqlQuery = filters.stashId
? sqlQuery
: sqlQuery.replace(/scenes\./g, '');
const results = await utilsApi.sql(sqlQuery);
const results = await utilsApi.sql(curatedSqlQuery);
// console.log(results);
const actorIds = results
.find((result) => result.columns[0].actor_ids && result.columns[1]['count(*)'])
?.data.map((row) => ({ key: row.actor_ids, doc_count: row['count(*)'] }))
.find((result) => (result.columns[0].actor_ids || result.columns[0]['scenes.actor_ids']) && result.columns[1]['count(*)'])
?.data.map((row) => ({ key: row.actor_ids || row['scenes.actor_ids'], doc_count: row['count(*)'] }))
|| [];
const tagIds = results
.find((result) => result.columns[0].tag_ids && result.columns[1]['count(*)'])
?.data.map((row) => ({ key: row.tag_ids, doc_count: row['count(*)'] }))
.find((result) => (result.columns[0].tag_ids || result.columns[0]['scenes.tag_ids']) && result.columns[1]['count(*)'])
?.data.map((row) => ({ key: row.tag_ids || row['scenes.tag_ids'], doc_count: row['count(*)'] }))
|| [];
const channelIds = results
.find((result) => result.columns[0].channel_id && result.columns[1]['count(*)'])
?.data.map((row) => ({ key: row.channel_id, doc_count: row['count(*)'] }))
.find((result) => (result.columns[0].channel_id || result.columns[0]['scenes.channel_id']) && result.columns[1]['count(*)'])
?.data.map((row) => ({ key: row.channel_id || row['scenes.channel_id'], doc_count: row['count(*)'] }))
|| [];
return {

View File

@@ -6,7 +6,7 @@ async function fetchMovies() {
.filter((movie) => movie.cast.length > 0
&& movie.genres.length > 0
&& movie.cast.every((actor) => actor.charCodeAt(0) >= 65)) // throw out movies with non-alphanumerical actor names
.map((movie, index) => ({ id: index, ...movie }));
.map((movie, index) => ({ id: index + 1, ...movie }));
const actors = Array.from(new Set(movies.flatMap((movie) => movie.cast))).sort();
const genres = Array.from(new Set(movies.flatMap((movie) => movie.genres)));