Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions whelk-core/src/main/groovy/whelk/search2/Disambiguate.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import groovy.transform.PackageScope;
import whelk.JsonLd;
import whelk.search2.querytree.*;
import whelk.util.Restrictions;

import java.time.format.DateTimeParseException;
import java.util.*;
Expand All @@ -14,6 +13,8 @@
import static whelk.JsonLd.LD_KEYS;
import static whelk.JsonLd.VOCAB_KEY;
import static whelk.JsonLd.looksLikeIri;
import static whelk.search2.Query.NONE_CATEGORY;
import static whelk.search2.Query.WORK_CATEGORY;
import static whelk.search2.QueryUtil.encodeUri;
import static whelk.search2.VocabMappings.expandPrefixed;

Expand Down Expand Up @@ -69,10 +70,10 @@ public Selector restrictByValue(Selector selector, String value) {
return switch (selector) {
case Property p -> restrictByValue(p, value);
case Path path -> {
var narrowed = restrictByValue(path.last(), value);
var coerced = restrictByValue(path.last(), value);
List<PathElement> newPath = new ArrayList<>(path.path());
newPath.removeLast();
newPath.addAll(narrowed.path());
newPath.addAll(coerced.path());
yield new Path(newPath, path.token());
}
case Key k -> k;
Expand All @@ -84,22 +85,22 @@ private boolean isRestrictedByValue(String propertyKey) {
}

private Property restrictByValue(Property property, String value) {
var narrowed = tryNarrow(property.name(), value);
if (narrowed != null) {
return new Property.NarrowedRestrictedProperty(property, narrowed, jsonLd);
var coercing = tryCoerce(property.name(), value);
if (coercing != null) {
return new Property.CoercingSubProperty(property, coercing, jsonLd);
} else if (property.name().equals(WORK_CATEGORY)) {
// FIXME: Don't hardcode
return new Property.CoercingSubProperty(property, NONE_CATEGORY, jsonLd);
}
return property;
}

private String tryNarrow(String property, String value) {
var narrowedByValue = vocabMappings.propertiesRestrictedByValue()
private String tryCoerce(String property, String value) {
var coercingSubPropertyKey = vocabMappings.propertiesRestrictedByValue()
.getOrDefault(property, Map.of())
.get(expandPrefixed(value));
if (narrowedByValue != null) {
return narrowedByValue.getFirst();
} else if (property.equals(Restrictions.CATEGORY)) {
// FIXME: Don't hardcode
return Restrictions.NONE_CATEGORY;
.get(value);
if (coercingSubPropertyKey != null) {
return coercingSubPropertyKey.getFirst();
}
return null;
}
Expand Down
2 changes: 1 addition & 1 deletion whelk-core/src/main/groovy/whelk/search2/ObjectQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ protected EsQuery doGetEsQuery() {
}

List<String> subjectTypes = Stream.concat(givenSubjectTypes.stream(), inferredSubjectTypes.stream()).toList();
var aggQuery = getEsAggQuery(subjectTypes);
var aggQuery = new LinkedHashMap<>(getEsAggQuery(subjectTypes));
aggQuery.putAll(getPAggQuery(predicateToSubjectTypes));
esQueryDsl.put("aggs", aggQuery);

Expand Down
56 changes: 30 additions & 26 deletions whelk-core/src/main/groovy/whelk/search2/Query.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import whelk.search2.querytree.YearRange;
import whelk.util.DocumentUtil;
import whelk.util.FresnelUtil;
import whelk.util.Restrictions;

import java.util.ArrayList;
import java.util.Collection;
Expand Down Expand Up @@ -71,6 +70,12 @@ public class Query {

private ReducedQueryTree fullQueryTree;

static final String WORK_CATEGORY = "librissearch:workCategory";

private static final String FIND_CATEGORY = "librissearch:findCategory";
private static final String IDENTIFY_CATEGORY = "librissearch:identifyCategory";
static final String NONE_CATEGORY = "librissearch:noneCategory";

public enum SearchMode {
SUGGEST,
STANDARD_SEARCH,
Expand Down Expand Up @@ -450,22 +455,21 @@ private static void addSliceToAggQuery(Map<String, Object> query,

Property property = slice.getProperty();

if (!slice.getShowIf().isEmpty()) {
if (!slice.getShowIf().isEmpty()
&& ctx.selectedFacets.isInactive(FIND_CATEGORY)
&& ctx.selectedFacets.isInactive(IDENTIFY_CATEGORY)
&& ctx.selectedFacets.isInactive(NONE_CATEGORY)) {
// Enable @none facet if find/identify/@none in query
// TODO don't hardcode this if we decide it is what we want
if (ctx.selectedFacets().getSelected(Restrictions.FIND_CATEGORY).isEmpty()
&& ctx.selectedFacets().getSelected(Restrictions.IDENTIFY_CATEGORY).isEmpty()
&& ctx.selectedFacets().getSelected(Restrictions.NONE_CATEGORY).isEmpty()) {
return;
}
return;
}

if (property.isRestrictedSubProperty() && !property.hasIndexKey()) {
// TODO: E.g. author (combining contribution.role and contribution.agent)
throw new RuntimeException("Can't handle combined fields in aggs query");
}

property.getAltSelectors(ctx.jsonLd, ctx.rdfSubjectTypes).stream()
property.getAltSelectors(ctx.jsonLd, ctx.rdfSubjectTypes, false).stream()
.map(s -> s.withPrependedMetaProperty(ctx.jsonLd))
.forEach(selector -> {
String field = selector.esField();
Expand Down Expand Up @@ -494,8 +498,8 @@ private static void addSliceToAggQuery(Map<String, Object> query,
m.remove(slice.subSlice().propertyKey());
}
// TODO don't hardcode this if we decide it is what we want
if (Restrictions.FIND_CATEGORY.equals(pKey) || Restrictions.IDENTIFY_CATEGORY.equals(pKey)) {
m.remove(Restrictions.NONE_CATEGORY);
if (FIND_CATEGORY.equals(pKey) || IDENTIFY_CATEGORY.equals(pKey)) {
m.remove(NONE_CATEGORY);
}
//if ("_categoryByCollection.@none".equals(pKey)) {
// m.remove("_categoryByCollection.find");
Expand All @@ -509,7 +513,7 @@ private static void addSliceToAggQuery(Map<String, Object> query,
query.put(field, filterWrap(aggs, property.name(), filter));
});
}

private static Map<String, Object> buildCoreAqqQuery(String field, AppParams.Slice slice, AggContext ctx) {
return buildCoreAqqQuery(field, slice, ctx, false);
}
Expand Down Expand Up @@ -667,14 +671,16 @@ public List<Map<String, Object>> getObservations(AppParams.Slice slice, Value pa

var property = slice.getProperty();
String propertyKey = slice.propertyKey();
List<Map<String, Object>> observations = new ArrayList<>();

Connective connective = selectedFacets.getConnective(propertyKey);

QueryTree qt = selectedFacets.isRangeFilter(propertyKey)
QueryTree qt = slice.isRange()
? qTree.removeAll(selectedFacets.getRangeSelected(propertyKey))
: qTree;

List<Condition> selected = selectedFacets.getSelected(propertyKey);
Connective connective = selectedFacets.inferConnective(propertyKey).orElse(slice.defaultConnective());

List<Map<String, Object>> observations = new ArrayList<>();

this.buckets.entrySet()
.stream()
// TODO only do this for nested aggs of the same property etc etc
Expand All @@ -697,7 +703,7 @@ public List<Map<String, Object>> getObservations(AppParams.Slice slice, Value pa
// TODO
boolean isSelected = selectedValue != null && !selectedValue.isEmpty()
? selectedValue.stream().anyMatch(n -> n instanceof Condition c2 && c2.value() instanceof Link l && v instanceof Link l2 && l.iri().equals(l2.iri()))
: selectedFacets.isSelected(c, propertyKey);
: selected.contains(c);

Consumer<QueryTree> addObservation = alteredTree -> {
Map<String, Object> observation = new LinkedHashMap<>();
Expand Down Expand Up @@ -731,9 +737,8 @@ public List<Map<String, Object>> getObservations(AppParams.Slice slice, Value pa
//List<Node> selected = selectedValue != null ? selectedValue : Collections.emptyList();
//addObservation.accept(qt.remove(selected).add(pv));
Predicate<Node> f = (Node n) -> n instanceof Condition c2
&& c2.selector().path().getLast() instanceof Property p
&& "category".equals(p.queryKey())
&& p.isRestrictedSubProperty();
&& c2.selector() instanceof Property p
&& p instanceof Property.CoercingSubProperty coercing && coercing.getSuperProperty().name().equals(WORK_CATEGORY);

var qt2 = qt.removeAll(qt.findTopNodesByCondition(n -> f.test(n) || n instanceof Or or && or.children().stream().anyMatch(f)));
if (selectedValue == null || !selectedValue.contains(c)) {
Expand All @@ -744,7 +749,6 @@ public List<Map<String, Object>> getObservations(AppParams.Slice slice, Value pa
return;
}

var selected = selectedFacets.getSelected(propertyKey);
if (isSelected) {
selected.stream()
.filter(c::equals)
Expand Down Expand Up @@ -810,14 +814,14 @@ public Map<String, Object> getSliceByDimension(List<AppParams.Slice> slices, Sel
/*
// Move @none to under selected find/identify
// TODO don't hardcode this if we decide it is what we want
var none = s.remove(Restrictions.NONE_CATEGORY);
var none = s.remove(NONE_CATEGORY);
if (none != null) {
var find = s.get(Restrictions.FIND_CATEGORY);
var find = s.get(FIND_CATEGORY);
if (find != null) {
DocumentUtil.traverse(find, (value, path) -> {
if (value instanceof Map m && m.containsKey("_selected") && m.get("_selected").equals(true) && !path.contains(Restrictions.NONE_CATEGORY)) {
if (value instanceof Map m && m.containsKey("_selected") && m.get("_selected").equals(true) && !path.contains(NONE_CATEGORY)) {
var newV = new HashMap<>(m);
((Map) newV.computeIfAbsent("sliceByDimension", k -> new HashMap<>())).put(Restrictions.NONE_CATEGORY, none);
((Map) newV.computeIfAbsent("sliceByDimension", k -> new HashMap<>())).put(NONE_CATEGORY, none);
return new DocumentUtil.Replace(newV);
}
return DocumentUtil.NOP;
Expand Down Expand Up @@ -865,13 +869,13 @@ private Map<String, Object> getSliceByDimension(List<AppParams.Slice> slices, Se
var sliceNode = new LinkedHashMap<>();
var observations = sliceResult.getObservations(slice, parentValue, mySelectedValue, selectedFacets);
if (!observations.isEmpty() || parentValue != null) {
if (selectedFacets.isRangeFilter(propertyKey)) {
if (slice.isRange()) {
sliceNode.put("search", getRangeTemplate(property));
}
sliceNode.put("dimension", property.name());
sliceNode.put("observation", observations);
sliceNode.put("maxItems", slice.size());
sliceNode.put("_connective", selectedFacets.getConnective(propertyKey).name());
sliceNode.put("_connective", selectedFacets.inferConnective(propertyKey).orElse(slice.defaultConnective()));
result.put(property.name(), sliceNode);
}
});
Expand Down
Loading
Loading