Changed scene year filter to range input.
This commit is contained in:
+25
-2
@@ -289,6 +289,14 @@ async function queryManticoreSql(filters, options) {
|
||||
builder.whereIn('effective_year', filters.years);
|
||||
}
|
||||
|
||||
if (typeof filters.yearRange?.min === 'number') {
|
||||
builder.where('effective_year', '>=', filters.yearRange.min);
|
||||
}
|
||||
|
||||
if (typeof filters.yearRange?.max === 'number') {
|
||||
builder.where('effective_year', '<=', filters.yearRange.max);
|
||||
}
|
||||
|
||||
filters.tagIds?.forEach((tagId) => {
|
||||
builder.where('any(tag_ids)', tagId);
|
||||
});
|
||||
@@ -428,9 +436,24 @@ export async function fetchMovies(filters, rawOptions, reqUser, context) {
|
||||
console.log(options);
|
||||
console.log(filters);
|
||||
|
||||
const result = await queryManticoreSql(filters, options);
|
||||
// an active year filter would narrow the year range to the filtered years, get the full range from a lightweight parallel query
|
||||
const hasYearFilter = options.aggregateYears && (filters.years?.length > 0 || !!filters.yearRange);
|
||||
|
||||
const aggYears = options.aggregateYears && result.aggregations.years.map((bucket) => ({ year: bucket.key, count: bucket.doc_count }));
|
||||
const yearsOptions = {
|
||||
...options,
|
||||
limit: 1,
|
||||
page: 1,
|
||||
aggregateActors: false,
|
||||
aggregateTags: false,
|
||||
aggregateChannels: false,
|
||||
};
|
||||
|
||||
const [result, yearsResult] = await Promise.all([
|
||||
queryManticoreSql(filters, options),
|
||||
hasYearFilter ? queryManticoreSql({ ...filters, years: [], yearRange: null }, yearsOptions) : null,
|
||||
]);
|
||||
|
||||
const aggYears = options.aggregateYears && (yearsResult || result).aggregations.years.map((bucket) => ({ year: bucket.key, count: bucket.doc_count }));
|
||||
|
||||
const actorCounts = options.aggregateActors && countAggregations(result.aggregations?.actorIds);
|
||||
const tagCounts = options.aggregateTags && countAggregations(result.aggregations?.tagIds);
|
||||
|
||||
+17
-5
@@ -558,6 +558,14 @@ async function queryManticoreSql(filters, options, _reqUser) {
|
||||
builder.whereIn('effective_year', filters.years);
|
||||
}
|
||||
|
||||
if (typeof filters.yearRange?.min === 'number') {
|
||||
builder.where('effective_year', '>=', filters.yearRange.min);
|
||||
}
|
||||
|
||||
if (typeof filters.yearRange?.max === 'number') {
|
||||
builder.where('effective_year', '<=', filters.yearRange.max);
|
||||
}
|
||||
|
||||
filters.tagIds?.forEach((tagId) => {
|
||||
if (filters.onlyActorTags) {
|
||||
builder.where((whereBuilder) => {
|
||||
@@ -776,18 +784,22 @@ export async function fetchScenes(filters, rawOptions, reqUser, context) {
|
||||
console.log('options', options);
|
||||
}
|
||||
|
||||
// an active count filter would narrow its own range to the filtered value, get the unfiltered ranges from a lightweight parallel query (~10ms vs 40-500ms for the main query with its actor and tag facets)
|
||||
// an active count or year filter would narrow its own aggregation to the filtered values, get the unfiltered ranges from a lightweight parallel query (~10ms vs 40-500ms for the main query with its actor and tag facets)
|
||||
// the range filters are stripped together, so with several active, each of their aggregations ignores the others
|
||||
const activeCountKeys = options.aggregateActorCounts
|
||||
? Object.keys(actorCountFilters).filter((key) => filters[actorCountFilters[key]])
|
||||
: [];
|
||||
|
||||
const countsFilters = Object.fromEntries(Object.entries(filters).filter(([key]) => !Object.values(actorCountFilters).includes(key)));
|
||||
const hasYearFilter = options.aggregateYears && (filters.years?.length > 0 || !!filters.yearRange);
|
||||
const rangeFilterKeys = [...Object.values(actorCountFilters), 'years', 'yearRange'];
|
||||
|
||||
const countsFilters = Object.fromEntries(Object.entries(filters).filter(([key]) => !rangeFilterKeys.includes(key)));
|
||||
|
||||
const countsOptions = {
|
||||
...options,
|
||||
limit: 1,
|
||||
page: 1,
|
||||
aggregateYears: false,
|
||||
aggregateYears: hasYearFilter,
|
||||
aggregateActors: false,
|
||||
aggregateTags: false,
|
||||
aggregateChannels: false,
|
||||
@@ -797,12 +809,12 @@ export async function fetchScenes(filters, rawOptions, reqUser, context) {
|
||||
|
||||
const [result, countsResult] = await Promise.all([
|
||||
queryManticoreSql(filters, options, reqUser),
|
||||
activeCountKeys.length > 0 ? queryManticoreSql(countsFilters, countsOptions, reqUser) : null,
|
||||
activeCountKeys.length > 0 || hasYearFilter ? queryManticoreSql(countsFilters, countsOptions, reqUser) : null,
|
||||
]);
|
||||
|
||||
console.timeEnd('manticore sql');
|
||||
|
||||
const aggYears = options.aggregateYears && result.aggregations.years.map((bucket) => ({ year: bucket.key, count: bucket.doc_count }));
|
||||
const aggYears = options.aggregateYears && (hasYearFilter ? countsResult : result).aggregations.years.map((bucket) => ({ year: bucket.key, count: bucket.doc_count }));
|
||||
const entityIds = options.aggregateChannels && [...(result.aggregations.channelIds || []), ...(result.aggregations.studioIds || [])];
|
||||
|
||||
// keyed by URL parameter, e.g. { group: [{ value: 2, count: 1234 }, ...], females: [...] }, sorted by value so the first and last bucket give the range
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
import { parseYears } from '../../utils/parse-range.js';
|
||||
import promiseProps from '../../utils/promise-props.js';
|
||||
import slugify from '../../utils/slugify.js';
|
||||
import { getIdsBySlug } from '../cache.js';
|
||||
@@ -10,7 +11,7 @@ export async function curateMoviesQuery(query) {
|
||||
return {
|
||||
scope: query.scope || 'latest',
|
||||
query: query.q,
|
||||
years: query.years?.split(',')?.map((year) => Number(year)).filter(Boolean) || [],
|
||||
...parseYears(query.years),
|
||||
actorIds: [query.actorId, ...(query.actors?.split(',') || []).map((identifier) => parseActorIdentifier(identifier)?.id)].filter(Boolean),
|
||||
tagIds: await getIdsBySlug([query.tagSlug, ...(query.tags?.split(',') || [])], 'tags'),
|
||||
entityId: query.e ? await getIdsBySlug([query.e], 'entities').then(([id]) => id) : query.entityId,
|
||||
|
||||
+4
-3
@@ -1,6 +1,6 @@
|
||||
import { Router } from 'express';
|
||||
|
||||
import { parseRange } from '../../utils/parse-range.js';
|
||||
import { parseRange, parseYears } from '../../utils/parse-range.js';
|
||||
|
||||
import promiseProps from '../../utils/promise-props.js';
|
||||
import slugify from '../../utils/slugify.js';
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
import { fetchStashByUsernameAndSlug } from '../stashes.js';
|
||||
|
||||
export async function curateScenesQuery(query) {
|
||||
const splitYears = query.years?.split(',') || [];
|
||||
const { years, yearRange } = parseYears(query.years);
|
||||
const splitTags = query.tags?.split(',') || [];
|
||||
const splitActors = query.actors?.split(',') || [];
|
||||
const splitEntities = query.e?.split(',') || [];
|
||||
@@ -39,7 +39,8 @@ export async function curateScenesQuery(query) {
|
||||
return {
|
||||
scope: query.scope || 'latest',
|
||||
query: query.q,
|
||||
years: splitYears.map((year) => Number(year)).filter(Boolean) || [],
|
||||
years,
|
||||
yearRange,
|
||||
actorIds: [query.actorId, ...splitActors.filter((actor) => actor.charAt(0) !== '!').map((identifier) => parseActorIdentifier(identifier)?.id)].filter(Boolean),
|
||||
notActorIds: splitActors.filter((actor) => actor.charAt(0) === '!').map((identifier) => parseActorIdentifier(identifier.slice(1))?.id).filter(Boolean),
|
||||
actorCount: parseRange(query.group),
|
||||
|
||||
Reference in New Issue
Block a user