percolator: Also support IndexOrDocValuesQuery

Otherwise ranges are never extracted properly.
This commit is contained in:
Martijn van Groningen 2017-07-31 23:14:35 +02:00
parent 6d68e8a10c
commit 5f36bdfda0
No known key found for this signature in database
GPG Key ID: AB236F4FCF2AF12A
3 changed files with 51 additions and 0 deletions

View File

@ -28,6 +28,7 @@ import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.DisjunctionMaxQuery;
import org.apache.lucene.search.IndexOrDocValuesQuery;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.PhraseQuery;
@ -85,6 +86,7 @@ final class QueryAnalyzer {
map.put(SynonymQuery.class, synonymQuery());
map.put(FunctionScoreQuery.class, functionScoreQuery());
map.put(PointRangeQuery.class, pointRangeQuery());
map.put(IndexOrDocValuesQuery.class, indexOrDocValuesQuery());
queryProcessors = Collections.unmodifiableMap(map);
}
@ -369,6 +371,13 @@ final class QueryAnalyzer {
return result;
}
private static Function<Query, Result> indexOrDocValuesQuery() {
return query -> {
IndexOrDocValuesQuery indexOrDocValuesQuery = (IndexOrDocValuesQuery) query;
return analyze(indexOrDocValuesQuery.getIndexQuery());
};
}
private static Result handleDisjunction(List<Query> disjunctions, int minimumShouldMatch, boolean otherClauses) {
boolean verified = minimumShouldMatch <= 1 && otherClauses == false;
Set<QueryExtraction> terms = new HashSet<>();

View File

@ -35,6 +35,7 @@ import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermInSetQuery;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TermRangeQuery;
@ -190,6 +191,32 @@ public class PercolatorFieldMapperTests extends ESSingleNodeTestCase {
assertThat(fields.get(1).binaryValue().utf8ToString(), equalTo("field\u0000term2"));
}
public void testExtractRanges() throws Exception {
addQueryFieldMappings();
BooleanQuery.Builder bq = new BooleanQuery.Builder();
Query rangeQuery1 = mapperService.documentMapper("doc").mappers().getMapper("number_field1").fieldType()
.rangeQuery(10, 20, true, true, null);
bq.add(rangeQuery1, Occur.MUST);
Query rangeQuery2 = mapperService.documentMapper("doc").mappers().getMapper("number_field1").fieldType()
.rangeQuery(15, 20, true, true, null);
bq.add(rangeQuery2, Occur.MUST);
DocumentMapper documentMapper = mapperService.documentMapper("doc");
PercolatorFieldMapper fieldMapper = (PercolatorFieldMapper) documentMapper.mappers().getMapper(fieldName);
ParseContext.InternalParseContext parseContext = new ParseContext.InternalParseContext(Settings.EMPTY,
mapperService.documentMapperParser(), documentMapper, null, null);
fieldMapper.processQuery(bq.build(), parseContext);
ParseContext.Document document = parseContext.doc();
PercolatorFieldMapper.FieldType fieldType = (PercolatorFieldMapper.FieldType) fieldMapper.fieldType();
assertThat(document.getField(fieldType.extractionResultField.name()).stringValue(), equalTo(EXTRACTION_PARTIAL));
List<IndexableField> fields = new ArrayList<>(Arrays.asList(document.getFields(fieldType.rangeField.name())));
fields.sort(Comparator.comparing(IndexableField::binaryValue));
assertThat(fields.size(), equalTo(1));
assertThat(IntPoint.decodeDimension(fields.get(0).binaryValue().bytes, 12), equalTo(15));
assertThat(IntPoint.decodeDimension(fields.get(0).binaryValue().bytes, 28), equalTo(20));
}
public void testExtractTermsAndRanges_failed() throws Exception {
addQueryFieldMappings();
TermRangeQuery query = new TermRangeQuery("field1", new BytesRef("a"), new BytesRef("z"), true, true);

View File

@ -24,6 +24,7 @@ import org.apache.lucene.document.HalfFloatPoint;
import org.apache.lucene.document.InetAddressPoint;
import org.apache.lucene.document.IntPoint;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.document.SortedNumericDocValuesField;
import org.apache.lucene.index.Term;
import org.apache.lucene.queries.BlendedTermQuery;
import org.apache.lucene.queries.CommonTermsQuery;
@ -32,6 +33,7 @@ import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.DisjunctionMaxQuery;
import org.apache.lucene.search.IndexOrDocValuesQuery;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.MultiPhraseQuery;
@ -676,6 +678,19 @@ public class QueryAnalyzerTests extends ESTestCase {
assertArrayEquals(ranges.get(0).range.upperPoint, InetAddressPoint.encode(InetAddresses.forString("192.168.1.255")));
}
public void testIndexOrDocValuesQuery() {
Query query = new IndexOrDocValuesQuery(IntPoint.newRangeQuery("_field", 10, 20),
SortedNumericDocValuesField.newSlowRangeQuery("_field", 10, 20));
Result result = analyze(query);
assertFalse(result.verified);
List<QueryAnalyzer.QueryExtraction> ranges = new ArrayList<>(result.extractions);
assertThat(ranges.size(), equalTo(1));
assertNull(ranges.get(0).term);
assertEquals("_field", ranges.get(0).range.fieldName);
assertDimension(ranges.get(0).range.lowerPoint, bytes -> IntPoint.encodeDimension(10, bytes, 0));
assertDimension(ranges.get(0).range.upperPoint, bytes -> IntPoint.encodeDimension(20, bytes, 0));
}
public void testPointRangeQuerySelectShortestRange() {
BooleanQuery.Builder boolQuery = new BooleanQuery.Builder();
boolQuery.add(LongPoint.newRangeQuery("_field1", 10, 20), BooleanClause.Occur.FILTER);