do not return anything if the field/value does not exist

The computation of proposals is done by searching for values in a
combined index. If one of the values didn't exist, then the algorithm
returned all values. Fixed by checking that we query only existing
field/values from the combined index.
This commit is contained in:
2019-04-20 19:48:51 +02:00
parent dbe0e02517
commit 56085061ed
6 changed files with 42 additions and 5 deletions

View File

@@ -5,6 +5,7 @@ import java.nio.file.Path;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicBoolean;
import org.lucares.collections.LongList;
import org.lucares.pdb.api.DateTimeRange;
@@ -250,6 +251,8 @@ public class QueryCompletionIndex implements AutoCloseable {
public SortedSet<String> find(final DateTimeRange dateRange, final String property, final String value,
final String field) {
final Tag tag = new Tag(property, value);
Preconditions.checkGreaterOrEqual(tag.getKey(), 0, "The property '{0}' is unkown", property);
Preconditions.checkGreaterOrEqual(tag.getValue(), 0, "The value '{0}' is unkown", value);
return find(dateRange, tag, field);
}
@@ -310,4 +313,15 @@ public class QueryCompletionIndex implements AutoCloseable {
});
return result;
}
public boolean hasField(final DateTimeRange dateRange, final String field) {
final AtomicBoolean found = new AtomicBoolean(false);
final PartitionIdSource partitionIdSource = new DatePartitioner(dateRange);
fieldIndex.visitValues(partitionIdSource, "", (k, v) -> {
if (k.equals(field)) {
found.set(true);
}
});
return found.get();
}
}

View File

@@ -42,10 +42,22 @@ public class FindValuesForQueryCompletion extends ExpressionVisitor<SortedSet<St
@Override
public SortedSet<String> visit(final Property property) {
final long start = System.nanoTime();
final TreeSet<String> result = new TreeSet<>();
final String fieldA = property.getProperty();
final String valueA = property.getValue().getValue();
final SortedSet<String> result = index.find(dateTimeRange, fieldA, valueA, field);
final boolean hasField = index.hasField(dateTimeRange, fieldA);
if (hasField) {
final SortedSet<String> allValuesForField = index.findAllValuesForField(dateTimeRange, fieldA);
final SortedSet<String> valuesA = GloblikePattern.filterValues(allValuesForField, valueA, TreeSet::new);
for (final String v : valuesA) {
final SortedSet<String> tmp = index.find(dateTimeRange, fieldA, v, field);
result.addAll(tmp);
}
}
METRIC_AND_CARET_LOGGER.debug("{}: {}ms", property, (System.nanoTime() - start) / 1_000_000.0);
return result;
}

View File

@@ -12,6 +12,10 @@ public class GloblikePattern {
private static final Logger LOGGER = LoggerFactory.getLogger(GloblikePattern.class);
enum FilterMode {
KEEP_EQUAL
}
static Pattern globlikeToRegex(final String globPattern) {
// a character that cannot be in the globPattern
final String dotPlaceholder = "\ue003"; // fourth character in the private use area
@@ -43,7 +47,7 @@ public class GloblikePattern {
for (final String value : availableValues) {
final Matcher matcher = pattern.matcher(value);
if (matcher.find() && !value.equals(valuePattern)) {
if (matcher.find()) {
result.add(value);
}
}

View File

@@ -170,8 +170,7 @@ public class NewProposerParser implements QueryConstants {
final SortedSet<String> candidateValuesCutAtDots = cutAtDots(candidateValues, queryWithCaretMarker);
// translate the candidate values to proposals
final List<Proposal> proposals = generateProposals(queryWithCaretMarker, expression,
candidateValuesCutAtDots);
final List<Proposal> proposals = generateProposals(queryWithCaretMarker, candidateValuesCutAtDots);
return proposals;
} catch (final SyntaxException e) {
@@ -186,7 +185,7 @@ public class NewProposerParser implements QueryConstants {
return grouper.group(candidateValues, queryWithCaretMarker);
}
private List<Proposal> generateProposals(final String queryWithCaretMarker, final Expression expression,
private List<Proposal> generateProposals(final String queryWithCaretMarker,
final SortedSet<String> candidateValues) {
final List<Proposal> proposals = new ArrayList<>();