LUCENE-9659 inequality support in payload check query (#2185)

Changes from SOLR-14787 supporting inequalities in SpanPayloadCheckQuery
This commit is contained in:
Kevin Watters 2021-02-17 09:48:50 -05:00 committed by GitHub
parent 3b6ba9e3e8
commit 890f570bf5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 1541 additions and 981 deletions

View File

@ -28,6 +28,7 @@ configure(project(":lucene").subprojects) { prj ->
spotless {
java {
toggleOffOn() // obviously, only to be used sparingly.
// TODO: Work out how to support multiple different header files (we have
// classes in the codebase that have original headers). We currently use
// Apache RAT to enforce headers so this is of lesser priority.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.lucene.queries.payloads;
import org.apache.lucene.util.BytesRef;
/** Defines an interface for testing if two payloads should be consider to match */
public interface PayloadMatcher {
/**
* This method tests if two BytesRef match.
*
* @param source left side of the compare
* @param payload right side of the compare
* @return true if the BytesRefs are matching, otherwise false.
*/
public boolean comparePayload(BytesRef source, BytesRef payload);
}

View File

@ -0,0 +1,247 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.lucene.queries.payloads;
import java.nio.charset.StandardCharsets;
import java.util.EnumMap;
import org.apache.lucene.queries.payloads.SpanPayloadCheckQuery.MatchOperation;
import org.apache.lucene.queries.payloads.SpanPayloadCheckQuery.PayloadType;
import org.apache.lucene.util.ArrayUtil;
import org.apache.lucene.util.BytesRef;
/**
* Creates a payload matcher object based on a payload type and an operation. PayloadTypes of
* INT,FLOAT, or STRING are supported. Inequality operations are supported.
*/
public class PayloadMatcherFactory {
private static final EnumMap<PayloadType, EnumMap<MatchOperation, PayloadMatcher>>
payloadCheckerOpTypeMap;
static {
payloadCheckerOpTypeMap = new EnumMap<>(PayloadType.class);
// ints
EnumMap<MatchOperation, PayloadMatcher> intCheckers = new EnumMap<>(MatchOperation.class);
intCheckers.put(MatchOperation.LT, new LTIntPayloadMatcher());
intCheckers.put(MatchOperation.LTE, new LTEIntPayloadMatcher());
intCheckers.put(MatchOperation.GT, new GTIntPayloadMatcher());
intCheckers.put(MatchOperation.GTE, new GTEIntPayloadMatcher());
EnumMap<MatchOperation, PayloadMatcher> floatCheckers = new EnumMap<>(MatchOperation.class);
floatCheckers.put(MatchOperation.LT, new LTFloatPayloadMatcher());
floatCheckers.put(MatchOperation.LTE, new LTEFloatPayloadMatcher());
floatCheckers.put(MatchOperation.GT, new GTFloatPayloadMatcher());
floatCheckers.put(MatchOperation.GTE, new GTEFloatPayloadMatcher());
// strings
EnumMap<MatchOperation, PayloadMatcher> stringCheckers = new EnumMap<>(MatchOperation.class);
stringCheckers.put(MatchOperation.LT, new LTStringPayloadMatcher());
stringCheckers.put(MatchOperation.LTE, new LTEStringPayloadMatcher());
stringCheckers.put(MatchOperation.GT, new GTStringPayloadMatcher());
stringCheckers.put(MatchOperation.GTE, new GTEStringPayloadMatcher());
// load the matcher maps per payload type
payloadCheckerOpTypeMap.put(PayloadType.INT, intCheckers);
payloadCheckerOpTypeMap.put(PayloadType.FLOAT, floatCheckers);
payloadCheckerOpTypeMap.put(PayloadType.STRING, stringCheckers);
}
/**
* Return a payload matcher for use in the SpanPayloadCheckQuery that will decode the ByteRef from
* a payload based on the payload type, and apply a matching inequality operations
* (eq,lt,lte,gt,and gte)
*
* @param payloadType the type of the payload to decode, STRING, INT, FLOAT
* @param op and inequalit operation as the test (example: eq for equals, gt for greater than)
* @return a payload matcher that decodes the payload and applies the operation inequality test.
*/
public static PayloadMatcher createMatcherForOpAndType(
PayloadType payloadType, MatchOperation op) {
// special optimization, binary/byte comparison
if (op == null || MatchOperation.EQ.equals(op)) {
return new EQPayloadMatcher();
}
// otherwise, we need to pay attention to the payload type and operation
EnumMap<MatchOperation, PayloadMatcher> opMap = payloadCheckerOpTypeMap.get(payloadType);
if (opMap != null) {
return opMap.get(op);
} else {
// Unknown op and payload type gets you an equals operator.
return new EQPayloadMatcher();
}
}
// Equality is the same for all payload types
private static class EQPayloadMatcher implements PayloadMatcher {
@Override
public boolean comparePayload(BytesRef source, BytesRef payload) {
return source.bytesEquals(payload);
}
}
private abstract static class StringPayloadMatcher implements PayloadMatcher {
@Override
public boolean comparePayload(BytesRef source, BytesRef payload) {
return stringCompare(
decodeString(payload.bytes, payload.offset, payload.length),
decodeString(source.bytes, source.offset, source.length));
}
private String decodeString(byte[] bytes, int offset, int length) {
return new String(
ArrayUtil.copyOfSubArray(bytes, offset, offset + length), StandardCharsets.UTF_8);
}
protected abstract boolean stringCompare(String val, String threshold);
}
private static class LTStringPayloadMatcher extends StringPayloadMatcher {
@Override
protected boolean stringCompare(String val, String thresh) {
int res = val.compareTo(thresh);
return (res < 0) ? true : false;
}
}
private static class LTEStringPayloadMatcher extends StringPayloadMatcher {
@Override
protected boolean stringCompare(String val, String thresh) {
int res = val.compareTo(thresh);
return (res < 1) ? true : false;
}
}
private static class GTStringPayloadMatcher extends StringPayloadMatcher {
@Override
protected boolean stringCompare(String val, String thresh) {
int res = val.compareTo(thresh);
return (res > 0) ? true : false;
}
}
private static class GTEStringPayloadMatcher extends StringPayloadMatcher {
@Override
protected boolean stringCompare(String val, String thresh) {
int res = val.compareTo(thresh);
return (res > -1) ? true : false;
}
}
private abstract static class IntPayloadMatcher implements PayloadMatcher {
@Override
public boolean comparePayload(BytesRef source, BytesRef payload) {
return intCompare(
decodeInt(payload.bytes, payload.offset), decodeInt(source.bytes, source.offset));
}
private int decodeInt(byte[] bytes, int offset) {
return ((bytes[offset] & 0xFF) << 24)
| ((bytes[offset + 1] & 0xFF) << 16)
| ((bytes[offset + 2] & 0xFF) << 8)
| (bytes[offset + 3] & 0xFF);
}
protected abstract boolean intCompare(int val, int threshold);
}
private static class LTIntPayloadMatcher extends IntPayloadMatcher {
@Override
public boolean intCompare(int val, int thresh) {
return (val < thresh);
}
}
private static class LTEIntPayloadMatcher extends IntPayloadMatcher {
@Override
public boolean intCompare(int val, int thresh) {
return (val <= thresh);
}
}
private static class GTIntPayloadMatcher extends IntPayloadMatcher {
@Override
public boolean intCompare(int val, int thresh) {
return (val > thresh);
}
}
private static class GTEIntPayloadMatcher extends IntPayloadMatcher {
@Override
protected boolean intCompare(int val, int thresh) {
return (val >= thresh);
}
}
private abstract static class FloatPayloadMatcher implements PayloadMatcher {
@Override
public boolean comparePayload(BytesRef source, BytesRef payload) {
return floatCompare(
decodeFloat(payload.bytes, payload.offset), decodeFloat(source.bytes, source.offset));
}
private float decodeFloat(byte[] bytes, int offset) {
return Float.intBitsToFloat(
((bytes[offset] & 0xFF) << 24)
| ((bytes[offset + 1] & 0xFF) << 16)
| ((bytes[offset + 2] & 0xFF) << 8)
| (bytes[offset + 3] & 0xFF));
}
protected abstract boolean floatCompare(float val, float threshold);
}
private static class LTFloatPayloadMatcher extends FloatPayloadMatcher {
@Override
protected boolean floatCompare(float val, float thresh) {
return (val < thresh);
}
}
private static class LTEFloatPayloadMatcher extends FloatPayloadMatcher {
@Override
protected boolean floatCompare(float val, float thresh) {
return (val <= thresh);
}
}
private static class GTFloatPayloadMatcher extends FloatPayloadMatcher {
@Override
protected boolean floatCompare(float val, float thresh) {
return (val > thresh);
}
}
private static class GTEFloatPayloadMatcher extends FloatPayloadMatcher {
@Override
protected boolean floatCompare(float val, float thresh) {
return (val >= thresh);
}
}
}

View File

@ -46,14 +46,56 @@ public class SpanPayloadCheckQuery extends SpanQuery {
protected final List<BytesRef> payloadToMatch;
protected final SpanQuery match;
protected final MatchOperation operation;
protected final PayloadType payloadType;
/** The payload type. This specifies the decoding of the ByteRef for the payload. */
public static enum PayloadType {
/** INT is for a 4 byte payload that is a packed integer */
INT,
/** FLOAT is a 4 byte payload decoded to a float(32bit). */
FLOAT,
/** STRING is a UTF8 encoded string, decoded from the byte array */
STRING
};
/** The payload type. This specifies the decoding of the ByteRef for the payload. */
public static enum MatchOperation {
/** Checks for binary equality of the byte array (default) */
EQ,
/** GT Matches if the payload value is greater than the reference */
GT,
/** GTE Matches if the payload value is greater than or equal to the reference */
GTE,
/** LT Matches if the payload value is less than the reference */
LT,
/** LTE Matches if the payload value is less than or equal to the reference */
LTE
};
/**
* @param match The underlying {@link org.apache.lucene.search.spans.SpanQuery} to check
* @param payloadToMatch The {@link java.util.List} of payloads to match
*/
public SpanPayloadCheckQuery(SpanQuery match, List<BytesRef> payloadToMatch) {
this(match, payloadToMatch, PayloadType.STRING, MatchOperation.EQ);
}
/**
* @param match The underlying {@link org.apache.lucene.search.spans.SpanQuery} to check
* @param payloadToMatch The {@link java.util.List} of payloads to match
* @param operation The equality check, lt, lte, gt, gte, or eq. Defaults to eq for equals)
* @param payloadType specify if the format of the bytes in the payload (String, Integer, or
* Float)
*/
public SpanPayloadCheckQuery(
SpanQuery match,
List<BytesRef> payloadToMatch,
PayloadType payloadType,
MatchOperation operation) {
this.match = match;
this.payloadToMatch = payloadToMatch;
this.payloadType = payloadType;
this.operation = operation;
}
@Override
@ -66,14 +108,19 @@ public class SpanPayloadCheckQuery extends SpanQuery {
throws IOException {
SpanWeight matchWeight = match.createWeight(searcher, scoreMode, boost);
return new SpanPayloadCheckWeight(
searcher, scoreMode.needsScores() ? getTermStates(matchWeight) : null, matchWeight, boost);
searcher,
scoreMode.needsScores() ? getTermStates(matchWeight) : null,
matchWeight,
boost,
payloadType);
}
@Override
public Query rewrite(IndexReader reader) throws IOException {
Query matchRewritten = match.rewrite(reader);
if (match != matchRewritten && matchRewritten instanceof SpanQuery) {
return new SpanPayloadCheckQuery((SpanQuery) matchRewritten, payloadToMatch);
return new SpanPayloadCheckQuery(
(SpanQuery) matchRewritten, payloadToMatch, payloadType, operation);
}
return super.rewrite(reader);
}
@ -94,7 +141,8 @@ public class SpanPayloadCheckQuery extends SpanQuery {
IndexSearcher searcher,
Map<Term, TermStates> termStates,
SpanWeight matchWeight,
float boost)
float boost,
PayloadType payloadType)
throws IOException {
super(SpanPayloadCheckQuery.this, searcher, termStates, boost);
this.matchWeight = matchWeight;
@ -154,8 +202,10 @@ public class SpanPayloadCheckQuery extends SpanQuery {
private class PayloadChecker implements SpanCollector {
int upto = 0;
boolean matches = true;
private int upto = 0;
private boolean matches = true;
private final PayloadMatcher payloadMatcher =
PayloadMatcherFactory.createMatcherForOpAndType(payloadType, operation);
@Override
public void collectLeaf(PostingsEnum postings, int position, Term term) throws IOException {
@ -177,7 +227,7 @@ public class SpanPayloadCheckQuery extends SpanQuery {
upto++;
return;
}
matches = payloadToMatch.get(upto).bytesEquals(payload);
matches = payloadMatcher.comparePayload(payloadToMatch.get(upto), payload);
upto++;
}
@ -202,15 +252,20 @@ public class SpanPayloadCheckQuery extends SpanQuery {
buffer.append(Term.toString(bytes));
buffer.append(';');
}
buffer.append(", payloadType:").append(payloadType).append(";");
buffer.append(", operation:").append(operation).append(";");
buffer.append(")");
return buffer.toString();
}
@SuppressWarnings("EqualsWhichDoesntCheckParameterClass") // it does but ides are easily confused
@Override
public boolean equals(Object other) {
return sameClassAs(other)
&& payloadToMatch.equals(((SpanPayloadCheckQuery) other).payloadToMatch)
&& match.equals(((SpanPayloadCheckQuery) other).match);
&& match.equals(((SpanPayloadCheckQuery) other).match)
&& operation.equals(((SpanPayloadCheckQuery) other).operation)
&& payloadType.equals(((SpanPayloadCheckQuery) other).payloadType);
}
@Override
@ -218,6 +273,8 @@ public class SpanPayloadCheckQuery extends SpanQuery {
int result = classHash();
result = 31 * result + Objects.hashCode(match);
result = 31 * result + Objects.hashCode(payloadToMatch);
result = 31 * result + Objects.hashCode(operation);
result = 31 * result + Objects.hashCode(payloadType);
return result;
}
}

View File

@ -17,8 +17,10 @@
package org.apache.lucene.queries.payloads;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.lucene.analysis.Analyzer;
@ -30,6 +32,8 @@ import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.queries.payloads.SpanPayloadCheckQuery.MatchOperation;
import org.apache.lucene.queries.payloads.SpanPayloadCheckQuery.PayloadType;
import org.apache.lucene.search.CheckHits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
@ -152,6 +156,156 @@ public class TestPayloadCheckQuery extends LuceneTestCase {
checkHits(query, new int[] {505});
}
public void testInequalityPayloadChecks() throws Exception {
// searching for the term five with a payload of either "pos: 0" or a payload of "pos: 1"
SpanQuery termFive = new SpanTermQuery(new Term("field", "five"));
SpanQuery termFifty = new SpanTermQuery(new Term("field", "fifty"));
BytesRef payloadZero = new BytesRef("pos: " + 0);
BytesRef payloadOne = new BytesRef("pos: " + 1);
BytesRef payloadTwo = new BytesRef("pos: " + 2);
BytesRef payloadThree = new BytesRef("pos: " + 3);
BytesRef payloadFour = new BytesRef("pos: " + 4);
BytesRef payloadFive = new BytesRef("pos: " + 5);
// Terms that equal five with a payload of "pos: 1"
SpanQuery stringEQ1 =
new SpanPayloadCheckQuery(
termFive,
Collections.singletonList(payloadOne),
SpanPayloadCheckQuery.PayloadType.STRING,
MatchOperation.EQ);
checkHits(stringEQ1, new int[] {25, 35, 45, 55, 65, 75, 85, 95});
// These queries return the same thing
SpanQuery stringLT =
new SpanPayloadCheckQuery(
termFive,
Collections.singletonList(payloadOne),
SpanPayloadCheckQuery.PayloadType.STRING,
MatchOperation.LT);
SpanQuery stringLTE =
new SpanPayloadCheckQuery(
termFive,
Collections.singletonList(payloadZero),
SpanPayloadCheckQuery.PayloadType.STRING,
MatchOperation.LTE);
// string less than and string less than or equal
checkHits(
stringLT,
new int[] {
5, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516,
517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534,
535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552,
553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570,
571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588,
589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599
});
checkHits(
stringLTE,
new int[] {
5, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516,
517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534,
535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552,
553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570,
571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588,
589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599
});
// greater than and greater than or equal tests.
SpanQuery stringGT =
new SpanPayloadCheckQuery(
termFive,
Collections.singletonList(payloadFour),
SpanPayloadCheckQuery.PayloadType.STRING,
MatchOperation.GT);
SpanQuery stringGTE =
new SpanPayloadCheckQuery(
termFive,
Collections.singletonList(payloadFive),
SpanPayloadCheckQuery.PayloadType.STRING,
MatchOperation.GTE);
checkHits(
stringGT,
new int[] {
1125, 1135, 1145, 1155, 1165, 1175, 1185, 1195, 1225, 1235, 1245, 1255, 1265, 1275, 1285,
1295, 1325, 1335, 1345, 1355, 1365, 1375, 1385, 1395, 1425, 1435, 1445, 1455, 1465, 1475,
1485, 1495, 1525, 1535, 1545, 1555, 1565, 1575, 1585, 1595, 1625, 1635, 1645, 1655, 1665,
1675, 1685, 1695, 1725, 1735, 1745, 1755, 1765, 1775, 1785, 1795, 1825, 1835, 1845, 1855,
1865, 1875, 1885, 1895, 1925, 1935, 1945, 1955, 1965, 1975, 1985, 1995
});
checkHits(
stringGTE,
new int[] {
1125, 1135, 1145, 1155, 1165, 1175, 1185, 1195, 1225, 1235, 1245, 1255, 1265, 1275, 1285,
1295, 1325, 1335, 1345, 1355, 1365, 1375, 1385, 1395, 1425, 1435, 1445, 1455, 1465, 1475,
1485, 1495, 1525, 1535, 1545, 1555, 1565, 1575, 1585, 1595, 1625, 1635, 1645, 1655, 1665,
1675, 1685, 1695, 1725, 1735, 1745, 1755, 1765, 1775, 1785, 1795, 1825, 1835, 1845, 1855,
1865, 1875, 1885, 1895, 1925, 1935, 1945, 1955, 1965, 1975, 1985, 1995
});
// now a not so happy path...
SpanQuery stringEQ2many =
new SpanPayloadCheckQuery(
termFive,
Arrays.asList(payloadOne, payloadZero),
SpanPayloadCheckQuery.PayloadType.STRING,
MatchOperation.EQ);
// fewer terms than payloads should not match anything, one wonders if this should be an error,
// but it's been explicitly ignored previously, so changing it is a possible back compat issue.
checkHits(stringEQ2many, new int[] {});
// now some straight forward two term cases...
SpanQuery stringEQ2 =
new SpanPayloadCheckQuery(
new SpanNearQuery(new SpanQuery[] {termFifty, termFive}, 0, true),
Arrays.asList(payloadZero, payloadOne),
SpanPayloadCheckQuery.PayloadType.STRING,
MatchOperation.EQ);
checkHits(stringEQ2, new int[] {55});
SpanQuery stringGT2 =
new SpanPayloadCheckQuery(
new SpanNearQuery(new SpanQuery[] {termFifty, termFive}, 0, true),
Arrays.asList(payloadZero, payloadOne),
SpanPayloadCheckQuery.PayloadType.STRING,
MatchOperation.GT);
checkHits(
stringGT2,
new int[] { // spotless:off
55, 155, 255, 355, 455, 555, 655, 755, 855, 955,
1055, 1155, 1255, 1355, 1455, 1555, 1655, 1755, 1855, 1955
}); // spotless:on
SpanQuery stringGTE2 =
new SpanPayloadCheckQuery(
new SpanNearQuery(new SpanQuery[] {termFifty, termFive}, 0, true),
Arrays.asList(payloadZero, payloadOne),
SpanPayloadCheckQuery.PayloadType.STRING,
MatchOperation.GTE);
checkHits(
stringGTE2,
new int[] { // spotless:off
55, 155, 255, 355, 455, 555, 655, 755, 855, 955,
1055, 1155, 1255, 1355, 1455, 1555, 1655, 1755, 1855, 1955
}); // spotless:on
SpanQuery stringLT2 =
new SpanPayloadCheckQuery(
new SpanNearQuery(new SpanQuery[] {termFifty, termFive}, 0, true),
Arrays.asList(payloadTwo, payloadThree),
SpanPayloadCheckQuery.PayloadType.STRING,
MatchOperation.LT);
checkHits(stringLT2, new int[] {55});
SpanQuery stringLTE2 =
new SpanPayloadCheckQuery(
new SpanNearQuery(new SpanQuery[] {termFifty, termFive}, 0, true),
Arrays.asList(payloadTwo, payloadThree),
SpanPayloadCheckQuery.PayloadType.STRING,
MatchOperation.LTE);
checkHits(stringLTE2, new int[] {55, 155, 255, 355, 455, 555, 655, 755, 855, 955, 1055});
// note: I can imagine support for SpanOrQuery might be interesting but that's for some other
// time, currently such support is made intractable by the fact that reset() gets called and
// sets "upto" back to zero between SpanOrQuery subclauses.
}
public void testUnorderedPayloadChecks() throws Exception {
SpanTermQuery term5 = new SpanTermQuery(new Term("field", "five"));
@ -226,6 +380,71 @@ public class TestPayloadCheckQuery extends LuceneTestCase {
assertFalse(query2.equals(query3));
assertFalse(query2.equals(query4));
assertFalse(query3.equals(query4));
// Create an integer and a float encoded payload
Integer i = 451;
BytesRef intPayload = new BytesRef(ByteBuffer.allocate(4).putInt(i).array());
Float e = 2.71828f;
BytesRef floatPayload = new BytesRef(ByteBuffer.allocate(4).putFloat(e).array());
SpanQuery floatLTQuery =
new SpanPayloadCheckQuery(
sq1, Collections.singletonList(floatPayload), PayloadType.FLOAT, MatchOperation.LT);
SpanQuery floatLTEQuery =
new SpanPayloadCheckQuery(
sq1, Collections.singletonList(floatPayload), PayloadType.FLOAT, MatchOperation.LTE);
SpanQuery floatGTQuery =
new SpanPayloadCheckQuery(
sq1, Collections.singletonList(floatPayload), PayloadType.FLOAT, MatchOperation.GT);
SpanQuery floatGTEQuery =
new SpanPayloadCheckQuery(
sq1, Collections.singletonList(floatPayload), PayloadType.FLOAT, MatchOperation.GTE);
SpanQuery intLTQuery =
new SpanPayloadCheckQuery(
sq1, Collections.singletonList(intPayload), PayloadType.INT, MatchOperation.LT);
SpanQuery intLTEQuery =
new SpanPayloadCheckQuery(
sq1, Collections.singletonList(intPayload), PayloadType.INT, MatchOperation.LTE);
SpanQuery intGTQuery =
new SpanPayloadCheckQuery(
sq1, Collections.singletonList(intPayload), PayloadType.INT, MatchOperation.GT);
SpanQuery intGTEQuery =
new SpanPayloadCheckQuery(
sq1, Collections.singletonList(intPayload), PayloadType.INT, MatchOperation.GT);
// string inequality checks
SpanQuery stringLTQuery =
new SpanPayloadCheckQuery(
sq1, Collections.singletonList(intPayload), PayloadType.STRING, MatchOperation.LT);
SpanQuery stringLTEQuery =
new SpanPayloadCheckQuery(
sq1, Collections.singletonList(intPayload), PayloadType.STRING, MatchOperation.LTE);
SpanQuery stringGTQuery =
new SpanPayloadCheckQuery(
sq1, Collections.singletonList(intPayload), PayloadType.STRING, MatchOperation.GT);
SpanQuery stringGTEQuery =
new SpanPayloadCheckQuery(
sq1, Collections.singletonList(intPayload), PayloadType.STRING, MatchOperation.GT);
SpanQuery stringEQQuery =
new SpanPayloadCheckQuery(
sq1, Collections.singletonList(intPayload), PayloadType.STRING, MatchOperation.EQ);
SpanQuery stringDefaultQuery =
new SpanPayloadCheckQuery(sq1, Collections.singletonList(intPayload));
assertTrue(stringDefaultQuery.equals(stringEQQuery));
assertFalse(stringDefaultQuery.equals(stringGTQuery));
assertFalse(stringDefaultQuery.equals(stringGTEQuery));
assertFalse(stringDefaultQuery.equals(stringLTQuery));
assertFalse(stringDefaultQuery.equals(stringLTEQuery));
assertFalse(floatLTQuery.equals(floatLTEQuery));
assertFalse(floatLTQuery.equals(floatGTQuery));
assertFalse(floatLTQuery.equals(floatGTEQuery));
assertFalse(floatLTQuery.equals(intLTQuery));
assertFalse(floatLTQuery.equals(intLTEQuery));
assertFalse(floatLTQuery.equals(intGTQuery));
assertFalse(floatLTQuery.equals(intGTEQuery));
}
public void testRewrite() throws IOException {