mirror of
https://github.com/stashapp/stash.git
synced 2025-12-06 16:34:02 +01:00
Optimize studio filter on performers (#1515)
This commit is contained in:
parent
86bd993b60
commit
d7439b4832
1 changed files with 17 additions and 44 deletions
|
|
@ -458,80 +458,53 @@ func performerGalleryCountCriterionHandler(qb *performerQueryBuilder, count *mod
|
||||||
func performerStudiosCriterionHandler(studios *models.HierarchicalMultiCriterionInput) criterionHandlerFunc {
|
func performerStudiosCriterionHandler(studios *models.HierarchicalMultiCriterionInput) criterionHandlerFunc {
|
||||||
return func(f *filterBuilder) {
|
return func(f *filterBuilder) {
|
||||||
if studios != nil {
|
if studios != nil {
|
||||||
var countCondition string
|
var clauseCondition string
|
||||||
var clauseJoin string
|
|
||||||
|
|
||||||
if studios.Modifier == models.CriterionModifierIncludes {
|
if studios.Modifier == models.CriterionModifierIncludes {
|
||||||
// return performers who appear in scenes/images/galleries with any of the given studios
|
// return performers who appear in scenes/images/galleries with any of the given studios
|
||||||
countCondition = " > 0"
|
clauseCondition = "NOT"
|
||||||
clauseJoin = " OR "
|
|
||||||
} else if studios.Modifier == models.CriterionModifierExcludes {
|
} else if studios.Modifier == models.CriterionModifierExcludes {
|
||||||
// exclude performers who appear in scenes/images/galleries with any of the given studios
|
// exclude performers who appear in scenes/images/galleries with any of the given studios
|
||||||
countCondition = " = 0"
|
clauseCondition = ""
|
||||||
clauseJoin = " AND "
|
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
inBinding := getInBinding(len(studios.Value))
|
|
||||||
|
|
||||||
formatMaps := []utils.StrFormatMap{
|
formatMaps := []utils.StrFormatMap{
|
||||||
{
|
{
|
||||||
"primaryTable": sceneTable,
|
"primaryTable": sceneTable,
|
||||||
"joinTable": performersScenesTable,
|
"joinTable": performersScenesTable,
|
||||||
"primaryFK": sceneIDColumn,
|
"primaryFK": sceneIDColumn,
|
||||||
"inBinding": inBinding,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"primaryTable": imageTable,
|
"primaryTable": imageTable,
|
||||||
"joinTable": performersImagesTable,
|
"joinTable": performersImagesTable,
|
||||||
"primaryFK": imageIDColumn,
|
"primaryFK": imageIDColumn,
|
||||||
"inBinding": inBinding,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"primaryTable": galleryTable,
|
"primaryTable": galleryTable,
|
||||||
"joinTable": performersGalleriesTable,
|
"joinTable": performersGalleriesTable,
|
||||||
"primaryFK": galleryIDColumn,
|
"primaryFK": galleryIDColumn,
|
||||||
"inBinding": inBinding,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// keeping existing behaviour for depth = 0 since it seems slightly better performing
|
const derivedStudioTable = "studio"
|
||||||
if studios.Depth == 0 {
|
const derivedPerformerStudioTable = "performer_studio"
|
||||||
templStr := `(SELECT COUNT(DISTINCT {primaryTable}.id) FROM {primaryTable}
|
addHierarchicalWithClause(f, studios.Value, derivedStudioTable, studioTable, "parent_id", studios.Depth)
|
||||||
LEFT JOIN {joinTable} ON {primaryTable}.id = {joinTable}.{primaryFK}
|
|
||||||
WHERE {joinTable}.performer_id = performers.id AND {primaryTable}.studio_id IN {inBinding})` + countCondition
|
|
||||||
|
|
||||||
var clauses []string
|
templStr := `SELECT performer_id FROM {primaryTable}
|
||||||
for _, c := range formatMaps {
|
INNER JOIN {joinTable} ON {primaryTable}.id = {joinTable}.{primaryFK}
|
||||||
clauses = append(clauses, utils.StrFormat(templStr, c))
|
INNER JOIN studio ON {primaryTable}.studio_id = studio.child_id`
|
||||||
}
|
|
||||||
|
|
||||||
var args []interface{}
|
var unions []string
|
||||||
for _, tagID := range studios.Value {
|
for _, c := range formatMaps {
|
||||||
args = append(args, tagID)
|
unions = append(unions, utils.StrFormat(templStr, c))
|
||||||
}
|
|
||||||
|
|
||||||
// this is a bit gross. We need the args three times
|
|
||||||
combinedArgs := append(args, append(args, args...)...)
|
|
||||||
|
|
||||||
f.addWhere(fmt.Sprintf("(%s)", strings.Join(clauses, clauseJoin)), combinedArgs...)
|
|
||||||
} else {
|
|
||||||
const derivedTable = "studio"
|
|
||||||
addHierarchicalWithClause(f, studios.Value, derivedTable, studioTable, "parent_id", studios.Depth)
|
|
||||||
|
|
||||||
templStr := `(SELECT COUNT(DISTINCT {primaryTable}.id) FROM {primaryTable}
|
|
||||||
LEFT JOIN {joinTable} ON {primaryTable}.id = {joinTable}.{primaryFK}
|
|
||||||
INNER JOIN studio ON {primaryTable}.studio_id = studio.child_id
|
|
||||||
WHERE {joinTable}.performer_id = performers.id)` + countCondition
|
|
||||||
|
|
||||||
var clauses []string
|
|
||||||
for _, c := range formatMaps {
|
|
||||||
clauses = append(clauses, utils.StrFormat(templStr, c))
|
|
||||||
}
|
|
||||||
|
|
||||||
f.addWhere(fmt.Sprintf("(%s)", strings.Join(clauses, clauseJoin)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f.addWith(fmt.Sprintf("%s AS (%s)", "performer_studio", strings.Join(unions, " UNION ")))
|
||||||
|
|
||||||
|
f.addJoin(derivedPerformerStudioTable, "", fmt.Sprintf("performers.id = %s.performer_id", derivedPerformerStudioTable))
|
||||||
|
f.addWhere(fmt.Sprintf("%s.performer_id IS %s NULL", derivedPerformerStudioTable, clauseCondition))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue