mirror of https://github.com/apache/lucene.git
LUCENE-7257: PointValues aggregated stats fail if the provided field does not have points on one of the leaves.
This commit is contained in:
parent
9ce830d8f2
commit
c7cdf2832b
|
@ -104,6 +104,10 @@ Bug Fixes
|
||||||
* LUCENE-7232: Fixed InetAddressPoint.newPrefixQuery, which was generating an
|
* LUCENE-7232: Fixed InetAddressPoint.newPrefixQuery, which was generating an
|
||||||
incorrect query when the prefix length was not a multiple of 8. (Adrien Grand)
|
incorrect query when the prefix length was not a multiple of 8. (Adrien Grand)
|
||||||
|
|
||||||
|
* LUCENE-7257: Fixed PointValues#size(IndexReader, String), docCount,
|
||||||
|
minPackedValue and maxPackedValue to skip leaves that do not have points
|
||||||
|
rather than raising an IllegalStateException. (Adrien Grand)
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
|
|
||||||
* LUCENE-7223: Improve XXXPoint javadocs to make it clear that you
|
* LUCENE-7223: Improve XXXPoint javadocs to make it clear that you
|
||||||
|
|
|
@ -87,43 +87,51 @@ public abstract class PointValues {
|
||||||
public static final int MAX_DIMENSIONS = BKDWriter.MAX_DIMS;
|
public static final int MAX_DIMENSIONS = BKDWriter.MAX_DIMS;
|
||||||
|
|
||||||
/** Return the cumulated number of points across all leaves of the given
|
/** Return the cumulated number of points across all leaves of the given
|
||||||
* {@link IndexReader}.
|
* {@link IndexReader}. Leaves that do not have points for the given field
|
||||||
|
* are ignored.
|
||||||
* @see PointValues#size(String) */
|
* @see PointValues#size(String) */
|
||||||
public static long size(IndexReader reader, String field) throws IOException {
|
public static long size(IndexReader reader, String field) throws IOException {
|
||||||
long size = 0;
|
long size = 0;
|
||||||
for (LeafReaderContext ctx : reader.leaves()) {
|
for (LeafReaderContext ctx : reader.leaves()) {
|
||||||
PointValues values = ctx.reader().getPointValues();
|
FieldInfo info = ctx.reader().getFieldInfos().fieldInfo(field);
|
||||||
if (values != null) {
|
if (info == null || info.getPointDimensionCount() == 0) {
|
||||||
size += values.size(field);
|
continue;
|
||||||
}
|
}
|
||||||
|
PointValues values = ctx.reader().getPointValues();
|
||||||
|
size += values.size(field);
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the cumulated number of docs that have points across all leaves
|
/** Return the cumulated number of docs that have points across all leaves
|
||||||
* of the given {@link IndexReader}.
|
* of the given {@link IndexReader}. Leaves that do not have points for the
|
||||||
|
* given field are ignored.
|
||||||
* @see PointValues#getDocCount(String) */
|
* @see PointValues#getDocCount(String) */
|
||||||
public static int getDocCount(IndexReader reader, String field) throws IOException {
|
public static int getDocCount(IndexReader reader, String field) throws IOException {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (LeafReaderContext ctx : reader.leaves()) {
|
for (LeafReaderContext ctx : reader.leaves()) {
|
||||||
PointValues values = ctx.reader().getPointValues();
|
FieldInfo info = ctx.reader().getFieldInfos().fieldInfo(field);
|
||||||
if (values != null) {
|
if (info == null || info.getPointDimensionCount() == 0) {
|
||||||
count += values.getDocCount(field);
|
continue;
|
||||||
}
|
}
|
||||||
|
PointValues values = ctx.reader().getPointValues();
|
||||||
|
count += values.getDocCount(field);
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the minimum packed values across all leaves of the given
|
/** Return the minimum packed values across all leaves of the given
|
||||||
* {@link IndexReader}.
|
* {@link IndexReader}. Leaves that do not have points for the given field
|
||||||
|
* are ignored.
|
||||||
* @see PointValues#getMinPackedValue(String) */
|
* @see PointValues#getMinPackedValue(String) */
|
||||||
public static byte[] getMinPackedValue(IndexReader reader, String field) throws IOException {
|
public static byte[] getMinPackedValue(IndexReader reader, String field) throws IOException {
|
||||||
byte[] minValue = null;
|
byte[] minValue = null;
|
||||||
for (LeafReaderContext ctx : reader.leaves()) {
|
for (LeafReaderContext ctx : reader.leaves()) {
|
||||||
PointValues values = ctx.reader().getPointValues();
|
FieldInfo info = ctx.reader().getFieldInfos().fieldInfo(field);
|
||||||
if (values == null) {
|
if (info == null || info.getPointDimensionCount() == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
PointValues values = ctx.reader().getPointValues();
|
||||||
byte[] leafMinValue = values.getMinPackedValue(field);
|
byte[] leafMinValue = values.getMinPackedValue(field);
|
||||||
if (leafMinValue == null) {
|
if (leafMinValue == null) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -145,15 +153,17 @@ public abstract class PointValues {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the maximum packed values across all leaves of the given
|
/** Return the maximum packed values across all leaves of the given
|
||||||
* {@link IndexReader}.
|
* {@link IndexReader}. Leaves that do not have points for the given field
|
||||||
|
* are ignored.
|
||||||
* @see PointValues#getMaxPackedValue(String) */
|
* @see PointValues#getMaxPackedValue(String) */
|
||||||
public static byte[] getMaxPackedValue(IndexReader reader, String field) throws IOException {
|
public static byte[] getMaxPackedValue(IndexReader reader, String field) throws IOException {
|
||||||
byte[] maxValue = null;
|
byte[] maxValue = null;
|
||||||
for (LeafReaderContext ctx : reader.leaves()) {
|
for (LeafReaderContext ctx : reader.leaves()) {
|
||||||
PointValues values = ctx.reader().getPointValues();
|
FieldInfo info = ctx.reader().getFieldInfos().fieldInfo(field);
|
||||||
if (values == null) {
|
if (info == null || info.getPointDimensionCount() == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
PointValues values = ctx.reader().getPointValues();
|
||||||
byte[] leafMaxValue = values.getMaxPackedValue(field);
|
byte[] leafMaxValue = values.getMaxPackedValue(field);
|
||||||
if (leafMaxValue == null) {
|
if (leafMaxValue == null) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.apache.lucene.document.FloatPoint;
|
||||||
import org.apache.lucene.document.IntPoint;
|
import org.apache.lucene.document.IntPoint;
|
||||||
import org.apache.lucene.document.LongPoint;
|
import org.apache.lucene.document.LongPoint;
|
||||||
import org.apache.lucene.document.StringField;
|
import org.apache.lucene.document.StringField;
|
||||||
|
import org.apache.lucene.document.Field.Store;
|
||||||
import org.apache.lucene.index.PointValues.IntersectVisitor;
|
import org.apache.lucene.index.PointValues.IntersectVisitor;
|
||||||
import org.apache.lucene.index.PointValues.Relation;
|
import org.apache.lucene.index.PointValues.Relation;
|
||||||
import org.apache.lucene.index.PointValues;
|
import org.apache.lucene.index.PointValues;
|
||||||
|
@ -652,6 +653,55 @@ public class TestPointValues extends LuceneTestCase {
|
||||||
dir.close();
|
dir.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testMergedStatsEmptyReader() throws IOException {
|
||||||
|
IndexReader reader = new MultiReader();
|
||||||
|
assertNull(PointValues.getMinPackedValue(reader, "field"));
|
||||||
|
assertNull(PointValues.getMaxPackedValue(reader, "field"));
|
||||||
|
assertEquals(0, PointValues.getDocCount(reader, "field"));
|
||||||
|
assertEquals(0, PointValues.size(reader, "field"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMergedStatsOneSegmentWithoutPoints() throws IOException {
|
||||||
|
Directory dir = new RAMDirectory();
|
||||||
|
IndexWriter w = new IndexWriter(dir, new IndexWriterConfig(null).setMergePolicy(NoMergePolicy.INSTANCE));
|
||||||
|
w.addDocument(new Document());
|
||||||
|
DirectoryReader.open(w).close();
|
||||||
|
Document doc = new Document();
|
||||||
|
doc.add(new IntPoint("field", Integer.MIN_VALUE));
|
||||||
|
w.addDocument(doc);
|
||||||
|
IndexReader reader = DirectoryReader.open(w);
|
||||||
|
|
||||||
|
assertArrayEquals(new byte[4], PointValues.getMinPackedValue(reader, "field"));
|
||||||
|
assertArrayEquals(new byte[4], PointValues.getMaxPackedValue(reader, "field"));
|
||||||
|
assertEquals(1, PointValues.getDocCount(reader, "field"));
|
||||||
|
assertEquals(1, PointValues.size(reader, "field"));
|
||||||
|
|
||||||
|
assertNull(PointValues.getMinPackedValue(reader, "field2"));
|
||||||
|
assertNull(PointValues.getMaxPackedValue(reader, "field2"));
|
||||||
|
assertEquals(0, PointValues.getDocCount(reader, "field2"));
|
||||||
|
assertEquals(0, PointValues.size(reader, "field2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMergedStatsAllPointsDeleted() throws IOException {
|
||||||
|
Directory dir = new RAMDirectory();
|
||||||
|
IndexWriter w = new IndexWriter(dir, new IndexWriterConfig(null));
|
||||||
|
w.addDocument(new Document());
|
||||||
|
Document doc = new Document();
|
||||||
|
doc.add(new IntPoint("field", Integer.MIN_VALUE));
|
||||||
|
doc.add(new StringField("delete", "yes", Store.NO));
|
||||||
|
w.addDocument(doc);
|
||||||
|
w.forceMerge(1);
|
||||||
|
w.deleteDocuments(new Term("delete", "yes"));
|
||||||
|
w.addDocument(new Document());
|
||||||
|
w.forceMerge(1);
|
||||||
|
IndexReader reader = DirectoryReader.open(w);
|
||||||
|
|
||||||
|
assertNull(PointValues.getMinPackedValue(reader, "field"));
|
||||||
|
assertNull(PointValues.getMaxPackedValue(reader, "field"));
|
||||||
|
assertEquals(0, PointValues.getDocCount(reader, "field"));
|
||||||
|
assertEquals(0, PointValues.size(reader, "field"));
|
||||||
|
}
|
||||||
|
|
||||||
public void testMergedStats() throws IOException {
|
public void testMergedStats() throws IOException {
|
||||||
final int iters = atLeast(3);
|
final int iters = atLeast(3);
|
||||||
for (int iter = 0; iter < iters; ++iter) {
|
for (int iter = 0; iter < iters; ++iter) {
|
||||||
|
|
Loading…
Reference in New Issue