Skip to content

Commit

Permalink
Add option to let facet group match on missing value
Browse files Browse the repository at this point in the history
  • Loading branch information
olovy committed Nov 20, 2023
1 parent 8311df6 commit 5b3e353
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 4 deletions.
4 changes: 3 additions & 1 deletion rest/src/main/groovy/whelk/rest/api/SearchUtils.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import groovy.util.logging.Log4j2 as Log
import whelk.Document
import whelk.JsonLd
import whelk.Whelk
import whelk.component.DocumentNormalizer
import whelk.exception.InvalidQueryException
import whelk.exception.WhelkRuntimeException
import whelk.search.ESQuery
Expand Down Expand Up @@ -831,6 +830,9 @@ class SearchUtils {
int limit = slice['itemLimit']
def connective = slice['connective']?.equals(OR.toString()) ? OR : AND
statsfind[key] = ['sort': 'value', 'sortOrder': 'desc', 'size': limit, 'connective': connective]
if (slice['_matchMissing']) { // FIXME: what should it be called?
statsfind[key]['_matchMissing'] = slice['_matchMissing']
}
}
return statsfind
}
Expand Down
22 changes: 19 additions & 3 deletions whelk-core/src/main/groovy/whelk/search/ESQuery.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -559,14 +559,14 @@ class ESQuery {
}

Set multiSelectable = multiSelectFacets(queryParameters)
Map<String, String> matchMissing = matchMissing(queryParameters)
getOrGroups(notNested).each { Map<String, ?> m ->
if (m.size() == 1 && m.keySet().first() in multiSelectable) {
multiSelectFilters[m.keySet().first()] = createBoolFilter(m)
multiSelectFilters[m.keySet().first()] = createBoolFilter(addMissingMatch(m, matchMissing))
}
else {
filters << createBoolFilter(m)
filters << createBoolFilter(addMissingMatch(m, matchMissing))
}

}
notNestedGroupsForNot.each { m ->
filtersForNot << createBoolFilter(m)
Expand All @@ -583,6 +583,14 @@ class ESQuery {
return new Tuple2(allFilters ? [['bool': allFilters]] : null, multiSelectFilters)
}

private static Map addMissingMatch(Map m, Map matchMissing) {
if (m.size() == 1 && m.keySet().first() in matchMissing) {
String field = matchMissing[m.keySet().first()]
m.put(EXISTS_PREFIX + field, ['false'])
}
return m
}

private getPrefixIfExists(String key) {
if (key.contains('.')) {
return key.substring(0, key.indexOf('.'))
Expand Down Expand Up @@ -642,6 +650,7 @@ class ESQuery {
if (p.size() > 0) {
result.add(p)
}

return result
}

Expand Down Expand Up @@ -836,6 +845,13 @@ class ESQuery {
} as Set<String>
}

@CompileStatic(TypeCheckingMode.SKIP)
static Map<String, String> matchMissing(Map queryParameters) {
getStatsRepr(queryParameters)
.findAll { key, value -> value['_matchMissing'] }
.collectEntries { key, value -> [key, value['_matchMissing'] as String]}
}

@CompileStatic(TypeCheckingMode.SKIP)
private static Map getStatsRepr(Map queryParameters) {
mapper.readValue(queryParameters.get('_statsrepr')?[0] ?: '{}', Map)
Expand Down

0 comments on commit 5b3e353

Please sign in to comment.