mirror of https://github.com/apache/lucene.git
add LongPoint.newSetQuery; improve PointInSetQuery.toString
This commit is contained in:
parent
3f5ed6eb67
commit
79c8bce1af
|
@ -219,14 +219,14 @@ public final class IntPoint extends Field {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a query efficiently finding all documents indexed with any of the specified 1D values.
|
||||
* Create a query matching any of the specified 1D values. This is the points equivalent of {@code TermsQuery}.
|
||||
*
|
||||
* @param field field name. must not be {@code null}.
|
||||
* @param valuesIn all int values to search for
|
||||
* @param valuesIn all int values to match
|
||||
*/
|
||||
public static PointInSetQuery newSetQuery(String field, int... valuesIn) throws IOException {
|
||||
|
||||
// Don't unexpectedly change the user's incoming array:
|
||||
// Don't unexpectedly change the user's incoming values array:
|
||||
int[] values = valuesIn.clone();
|
||||
|
||||
Arrays.sort(values);
|
||||
|
|
|
@ -16,8 +16,13 @@
|
|||
*/
|
||||
package org.apache.lucene.document;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.lucene.search.PointInSetQuery;
|
||||
import org.apache.lucene.search.PointRangeQuery;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.BytesRefIterator;
|
||||
import org.apache.lucene.util.NumericUtils;
|
||||
|
||||
/**
|
||||
|
@ -212,4 +217,44 @@ public final class LongPoint extends Field {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a query matching any of the specified 1D values. This is the points equivalent of {@code TermsQuery}.
|
||||
*
|
||||
* @param field field name. must not be {@code null}.
|
||||
* @param valuesIn all int values to match
|
||||
*/
|
||||
public static PointInSetQuery newSetQuery(String field, long... valuesIn) throws IOException {
|
||||
|
||||
// Don't unexpectedly change the user's incoming values array:
|
||||
long[] values = valuesIn.clone();
|
||||
|
||||
Arrays.sort(values);
|
||||
|
||||
final BytesRef value = new BytesRef(new byte[Long.BYTES]);
|
||||
value.length = Long.BYTES;
|
||||
|
||||
return new PointInSetQuery(field, 1, Long.BYTES,
|
||||
new BytesRefIterator() {
|
||||
|
||||
int upto;
|
||||
|
||||
@Override
|
||||
public BytesRef next() {
|
||||
if (upto == values.length) {
|
||||
return null;
|
||||
} else {
|
||||
LongPoint.encodeDimension(values[upto], value.bytes, 0);
|
||||
upto++;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}) {
|
||||
@Override
|
||||
protected String toString(byte[] value) {
|
||||
assert value.length == Long.BYTES;
|
||||
return Long.toString(decodeDimension(value, 0));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -320,24 +320,25 @@ public class PointInSetQuery extends Query {
|
|||
@Override
|
||||
public String toString(String field) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(getClass().getSimpleName());
|
||||
sb.append(':');
|
||||
if (this.field.equals(field) == false) {
|
||||
sb.append(" field=");
|
||||
sb.append(this.field);
|
||||
sb.append(':');
|
||||
}
|
||||
|
||||
sb.append(" points:");
|
||||
sb.append("{");
|
||||
|
||||
TermIterator iterator = sortedPackedPoints.iterator();
|
||||
byte[] pointBytes = new byte[numDims * bytesPerDim];
|
||||
boolean first = true;
|
||||
for (BytesRef point = iterator.next(); point != null; point = iterator.next()) {
|
||||
sb.append(' ');
|
||||
if (first == false) {
|
||||
sb.append(" ");
|
||||
}
|
||||
first = false;
|
||||
System.arraycopy(point.bytes, point.offset, pointBytes, 0, pointBytes.length);
|
||||
sb.append(toString(pointBytes));
|
||||
}
|
||||
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
|
|
@ -1127,11 +1127,31 @@ public class TestPointQueries extends LuceneTestCase {
|
|||
return values;
|
||||
}
|
||||
|
||||
private static int randomIntValue(Integer min, Integer max) {
|
||||
if (min == null) {
|
||||
return random().nextInt();
|
||||
} else {
|
||||
return TestUtil.nextInt(random(), min, max);
|
||||
}
|
||||
}
|
||||
|
||||
public void testRandomPointInSetQuery() throws Exception {
|
||||
|
||||
boolean useNarrowRange = random().nextBoolean();
|
||||
final Integer valueMin;
|
||||
final Integer valueMax;
|
||||
if (useNarrowRange) {
|
||||
int gap = random().nextInt(100);
|
||||
valueMin = random().nextInt(Integer.MAX_VALUE-gap);
|
||||
valueMax = valueMin + gap;
|
||||
} else {
|
||||
valueMin = null;
|
||||
valueMax = null;
|
||||
}
|
||||
final Set<Integer> valuesSet = new HashSet<>();
|
||||
int numValues = TestUtil.nextInt(random(), 1, 100);
|
||||
while (valuesSet.size() < numValues) {
|
||||
valuesSet.add(random().nextInt());
|
||||
valuesSet.add(randomIntValue(valueMin, valueMax));
|
||||
}
|
||||
int[] values = toArray(valuesSet);
|
||||
int numDocs = TestUtil.nextInt(random(), 1, 10000);
|
||||
|
@ -1211,8 +1231,7 @@ public class TestPointQueries extends LuceneTestCase {
|
|||
|
||||
int numExtraValuesToQuery = random().nextInt(20);
|
||||
while (valuesToQuery.size() < numValidValuesToQuery + numExtraValuesToQuery) {
|
||||
// nocommit fix test to sometimes use "narrow" range of values
|
||||
valuesToQuery.add(random().nextInt());
|
||||
valuesToQuery.add(randomIntValue(valueMin, valueMax));
|
||||
}
|
||||
|
||||
int expectedCount = 0;
|
||||
|
@ -1241,8 +1260,6 @@ public class TestPointQueries extends LuceneTestCase {
|
|||
IOUtils.close(r, dir);
|
||||
}
|
||||
|
||||
// nocommit fix existing randomized tests to sometimes randomly use PointInSet instead
|
||||
|
||||
// nocommit need 2D test too
|
||||
|
||||
public void testBasicPointInSetQuery() throws Exception {
|
||||
|
@ -1253,14 +1270,17 @@ public class TestPointQueries extends LuceneTestCase {
|
|||
|
||||
Document doc = new Document();
|
||||
doc.add(new IntPoint("int", 17));
|
||||
doc.add(new LongPoint("long", 17));
|
||||
w.addDocument(doc);
|
||||
|
||||
doc = new Document();
|
||||
doc.add(new IntPoint("int", 42));
|
||||
doc.add(new LongPoint("long", 42));
|
||||
w.addDocument(doc);
|
||||
|
||||
doc = new Document();
|
||||
doc.add(new IntPoint("int", 97));
|
||||
doc.add(new LongPoint("long", 97));
|
||||
w.addDocument(doc);
|
||||
|
||||
IndexReader r = DirectoryReader.open(w);
|
||||
|
@ -1271,6 +1291,46 @@ public class TestPointQueries extends LuceneTestCase {
|
|||
assertEquals(3, s.count(IntPoint.newSetQuery("int", -7, 17, 42, 97)));
|
||||
assertEquals(3, s.count(IntPoint.newSetQuery("int", 17, 20, 42, 97)));
|
||||
assertEquals(3, s.count(IntPoint.newSetQuery("int", 17, 105, 42, 97)));
|
||||
|
||||
assertEquals(0, s.count(LongPoint.newSetQuery("long", 16)));
|
||||
assertEquals(1, s.count(LongPoint.newSetQuery("long", 17)));
|
||||
assertEquals(3, s.count(LongPoint.newSetQuery("long", 17, 97, 42)));
|
||||
assertEquals(3, s.count(LongPoint.newSetQuery("long", -7, 17, 42, 97)));
|
||||
assertEquals(3, s.count(LongPoint.newSetQuery("long", 17, 20, 42, 97)));
|
||||
assertEquals(3, s.count(LongPoint.newSetQuery("long", 17, 105, 42, 97)));
|
||||
|
||||
w.close();
|
||||
r.close();
|
||||
dir.close();
|
||||
}
|
||||
|
||||
public void testBasicMultiValuedPointInSetQuery() throws Exception {
|
||||
Directory dir = newDirectory();
|
||||
IndexWriterConfig iwc = newIndexWriterConfig();
|
||||
iwc.setCodec(getCodec());
|
||||
IndexWriter w = new IndexWriter(dir, iwc);
|
||||
|
||||
Document doc = new Document();
|
||||
doc.add(new IntPoint("int", 17));
|
||||
doc.add(new IntPoint("int", 42));
|
||||
doc.add(new LongPoint("long", 17));
|
||||
doc.add(new LongPoint("long", 42));
|
||||
w.addDocument(doc);
|
||||
|
||||
IndexReader r = DirectoryReader.open(w);
|
||||
IndexSearcher s = newSearcher(r);
|
||||
assertEquals(0, s.count(IntPoint.newSetQuery("int", 16)));
|
||||
assertEquals(1, s.count(IntPoint.newSetQuery("int", 17)));
|
||||
assertEquals(1, s.count(IntPoint.newSetQuery("int", 17, 97, 42)));
|
||||
assertEquals(1, s.count(IntPoint.newSetQuery("int", -7, 17, 42, 97)));
|
||||
assertEquals(0, s.count(IntPoint.newSetQuery("int", 16, 20, 41, 97)));
|
||||
|
||||
assertEquals(0, s.count(LongPoint.newSetQuery("long", 16)));
|
||||
assertEquals(1, s.count(LongPoint.newSetQuery("long", 17)));
|
||||
assertEquals(1, s.count(LongPoint.newSetQuery("long", 17, 97, 42)));
|
||||
assertEquals(1, s.count(LongPoint.newSetQuery("long", -7, 17, 42, 97)));
|
||||
assertEquals(0, s.count(LongPoint.newSetQuery("long", 16, 20, 41, 97)));
|
||||
|
||||
w.close();
|
||||
r.close();
|
||||
dir.close();
|
||||
|
@ -1290,6 +1350,7 @@ public class TestPointQueries extends LuceneTestCase {
|
|||
}
|
||||
Document doc = new Document();
|
||||
doc.add(new IntPoint("int", x));
|
||||
doc.add(new LongPoint("long", x));
|
||||
w.addDocument(doc);
|
||||
}
|
||||
|
||||
|
@ -1300,12 +1361,18 @@ public class TestPointQueries extends LuceneTestCase {
|
|||
assertEquals(zeroCount, s.count(IntPoint.newSetQuery("int", 7, 0)));
|
||||
assertEquals(10000-zeroCount, s.count(IntPoint.newSetQuery("int", 1)));
|
||||
assertEquals(0, s.count(IntPoint.newSetQuery("int", 2)));
|
||||
|
||||
assertEquals(zeroCount, s.count(LongPoint.newSetQuery("long", 0)));
|
||||
assertEquals(zeroCount, s.count(LongPoint.newSetQuery("long", 0, -7)));
|
||||
assertEquals(zeroCount, s.count(LongPoint.newSetQuery("long", 7, 0)));
|
||||
assertEquals(10000-zeroCount, s.count(LongPoint.newSetQuery("long", 1)));
|
||||
assertEquals(0, s.count(LongPoint.newSetQuery("long", 2)));
|
||||
w.close();
|
||||
r.close();
|
||||
dir.close();
|
||||
}
|
||||
|
||||
public void testPointInSetQueryManyEqualValuesBigGap() throws Exception {
|
||||
public void testPointInSetQueryManyEqualValuesWithBigGap() throws Exception {
|
||||
Directory dir = newDirectory();
|
||||
IndexWriterConfig iwc = newIndexWriterConfig();
|
||||
iwc.setCodec(getCodec());
|
||||
|
@ -1319,6 +1386,7 @@ public class TestPointQueries extends LuceneTestCase {
|
|||
}
|
||||
Document doc = new Document();
|
||||
doc.add(new IntPoint("int", x));
|
||||
doc.add(new LongPoint("long", x));
|
||||
w.addDocument(doc);
|
||||
}
|
||||
|
||||
|
@ -1329,6 +1397,12 @@ public class TestPointQueries extends LuceneTestCase {
|
|||
assertEquals(zeroCount, s.count(IntPoint.newSetQuery("int", 7, 0)));
|
||||
assertEquals(10000-zeroCount, s.count(IntPoint.newSetQuery("int", 200)));
|
||||
assertEquals(0, s.count(IntPoint.newSetQuery("int", 2)));
|
||||
|
||||
assertEquals(zeroCount, s.count(LongPoint.newSetQuery("long", 0)));
|
||||
assertEquals(zeroCount, s.count(LongPoint.newSetQuery("long", 0, -7)));
|
||||
assertEquals(zeroCount, s.count(LongPoint.newSetQuery("long", 7, 0)));
|
||||
assertEquals(10000-zeroCount, s.count(LongPoint.newSetQuery("long", 200)));
|
||||
assertEquals(0, s.count(LongPoint.newSetQuery("long", 2)));
|
||||
w.close();
|
||||
r.close();
|
||||
dir.close();
|
||||
|
@ -1347,4 +1421,12 @@ public class TestPointQueries extends LuceneTestCase {
|
|||
});
|
||||
assertEquals("packed point length should be 12 but got 3; field=\"foo\" numDims=3 bytesPerDim=4", expected.getMessage());
|
||||
}
|
||||
|
||||
public void testPointInSetQueryToString() throws Exception {
|
||||
// int
|
||||
assertEquals("int:{-42 18}", IntPoint.newSetQuery("int", -42, 18).toString());
|
||||
|
||||
// long
|
||||
assertEquals("long:{-42 18}", LongPoint.newSetQuery("long", -42L, 18L).toString());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue