mirror of https://github.com/apache/lucene.git
LUCENE-6560: BKDPointInBBOxQuery now handles dateline crossing correctly
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1685526 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a1876da5ee
commit
0ef770fcd0
|
@ -122,6 +122,9 @@ Bug fixes
|
||||||
* LUCENE-6558: Highlighters now work with CustomScoreQuery (Cao Manh
|
* LUCENE-6558: Highlighters now work with CustomScoreQuery (Cao Manh
|
||||||
Dat via Mike McCandless)
|
Dat via Mike McCandless)
|
||||||
|
|
||||||
|
* LUCENE-6560: BKDPointInBBoxQuery now handles "dateline crossing"
|
||||||
|
correctly (Nick Knize, Mike McCandless)
|
||||||
|
|
||||||
Changes in Runtime Behavior
|
Changes in Runtime Behavior
|
||||||
|
|
||||||
* LUCENE-6501: The subreader structure in ParallelCompositeReader
|
* LUCENE-6501: The subreader structure in ParallelCompositeReader
|
||||||
|
|
|
@ -17,13 +17,13 @@ package org.apache.lucene.bkdtree;
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.IOException;
|
import org.apache.lucene.index.IndexReader;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.apache.lucene.index.LeafReader;
|
import org.apache.lucene.index.LeafReader;
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
import org.apache.lucene.index.SortedNumericDocValues;
|
import org.apache.lucene.index.SortedNumericDocValues;
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
|
import org.apache.lucene.search.BooleanClause;
|
||||||
|
import org.apache.lucene.search.BooleanQuery;
|
||||||
import org.apache.lucene.search.DocIdSet;
|
import org.apache.lucene.search.DocIdSet;
|
||||||
import org.apache.lucene.search.DocIdSetIterator;
|
import org.apache.lucene.search.DocIdSetIterator;
|
||||||
import org.apache.lucene.search.Explanation;
|
import org.apache.lucene.search.Explanation;
|
||||||
|
@ -34,6 +34,9 @@ import org.apache.lucene.search.Weight;
|
||||||
import org.apache.lucene.util.Bits;
|
import org.apache.lucene.util.Bits;
|
||||||
import org.apache.lucene.util.ToStringUtils;
|
import org.apache.lucene.util.ToStringUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/** Finds all previously indexed points that fall within the specified boundings box.
|
/** Finds all previously indexed points that fall within the specified boundings box.
|
||||||
*
|
*
|
||||||
* <p>The field must be indexed with {@link BKDTreeDocValuesFormat}, and {@link BKDPointField} added per document.
|
* <p>The field must be indexed with {@link BKDTreeDocValuesFormat}, and {@link BKDPointField} added per document.
|
||||||
|
@ -163,6 +166,28 @@ public class BKDPointInBBoxQuery extends Query {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query rewrite(IndexReader reader) throws IOException {
|
||||||
|
// Crosses date line: we just rewrite into OR of two bboxes:
|
||||||
|
if (maxLon < minLon) {
|
||||||
|
|
||||||
|
// Disable coord here because a multi-valued doc could match both rects and get unfairly boosted:
|
||||||
|
BooleanQuery q = new BooleanQuery(true);
|
||||||
|
|
||||||
|
// E.g.: maxLon = -179, minLon = 179
|
||||||
|
BKDPointInBBoxQuery left = new BKDPointInBBoxQuery(field, minLat, maxLat, BKDTreeWriter.MIN_LON_INCL, maxLon);
|
||||||
|
left.setBoost(getBoost());
|
||||||
|
q.add(new BooleanClause(left, BooleanClause.Occur.SHOULD));
|
||||||
|
BKDPointInBBoxQuery right = new BKDPointInBBoxQuery(field, minLat, maxLat, minLon, BKDTreeWriter.MAX_LON_INCL);
|
||||||
|
right.setBoost(getBoost());
|
||||||
|
q.add(new BooleanClause(right, BooleanClause.Occur.SHOULD));
|
||||||
|
return q;
|
||||||
|
} else {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hash = super.hashCode();
|
int hash = super.hashCode();
|
||||||
|
|
|
@ -452,18 +452,27 @@ public class TestBKDTree extends LuceneTestCase {
|
||||||
lat1 = x;
|
lat1 = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean crossesDateLine;
|
||||||
if (lon1 < lon0) {
|
if (lon1 < lon0) {
|
||||||
double x = lon0;
|
if (random().nextBoolean()) {
|
||||||
lon0 = lon1;
|
double x = lon0;
|
||||||
lon1 = x;
|
lon0 = lon1;
|
||||||
|
lon1 = x;
|
||||||
|
crossesDateLine = false;
|
||||||
|
} else {
|
||||||
|
crossesDateLine = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
crossesDateLine = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VERBOSE) {
|
if (VERBOSE) {
|
||||||
System.out.println("\nTEST: iter=" + iter + " lat=" + lat0 + " TO " + lat1 + " lon=" + lon0 + " TO " + lon1);
|
System.out.println("\nTEST: iter=" + iter + " lat=" + lat0 + " TO " + lat1 + " lon=" + lon0 + " TO " + lon1 + " crossesDateLine=" + crossesDateLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
Query query;
|
Query query;
|
||||||
if (random().nextBoolean()) {
|
// TODO: get poly query working with dateline crossing too (how?)!
|
||||||
|
if (crossesDateLine || random().nextBoolean()) {
|
||||||
query = new BKDPointInBBoxQuery("point", lat0, lat1, lon0, lon1);
|
query = new BKDPointInBBoxQuery("point", lat0, lat1, lon0, lon1);
|
||||||
} else {
|
} else {
|
||||||
double[] lats = new double[5];
|
double[] lats = new double[5];
|
||||||
|
@ -522,7 +531,7 @@ public class TestBKDTree extends LuceneTestCase {
|
||||||
// The poly check quantizes slightly differently, so we allow for boundary cases to disagree
|
// The poly check quantizes slightly differently, so we allow for boundary cases to disagree
|
||||||
} else {
|
} else {
|
||||||
// We do exact quantized comparison so the bbox query should never disagree:
|
// We do exact quantized comparison so the bbox query should never disagree:
|
||||||
fail(Thread.currentThread().getName() + ": iter=" + iter + " id=" + id + " docID=" + docID + " lat=" + lats[id] + " lon=" + lons[id] + " (bbox: lat=" + lat0 + " TO " + lat1 + " lon=" + lon0 + " TO " + lon1 + ") expected " + expected + " but got: " + hits.get(docID) + " deleted?=" + deleted.contains(id) + " query=" + query);
|
fail(Thread.currentThread().getName() + ": iter=" + iter + " id=" + id + " docID=" + docID + " lat=" + lats[id] + " lon=" + lons[id] + " (bbox: lat=" + lat0 + " TO " + lat1 + " lon=" + lon0 + " TO " + lon1 + ") expected " + expected + " but got: " + hits.get(docID) + " deleted?=" + deleted.contains(id) + " query=" + query + " crossesDateLine=" + crossesDateLine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -553,10 +562,18 @@ public class TestBKDTree extends LuceneTestCase {
|
||||||
int pointLatEnc = BKDTreeWriter.encodeLat(pointLat);
|
int pointLatEnc = BKDTreeWriter.encodeLat(pointLat);
|
||||||
int pointLonEnc = BKDTreeWriter.encodeLon(pointLon);
|
int pointLonEnc = BKDTreeWriter.encodeLon(pointLon);
|
||||||
|
|
||||||
return pointLatEnc >= rectLatMinEnc &&
|
if (rectLonMin < rectLonMax) {
|
||||||
pointLatEnc < rectLatMaxEnc &&
|
return pointLatEnc >= rectLatMinEnc &&
|
||||||
pointLonEnc >= rectLonMinEnc &&
|
pointLatEnc < rectLatMaxEnc &&
|
||||||
pointLonEnc < rectLonMaxEnc;
|
pointLonEnc >= rectLonMinEnc &&
|
||||||
|
pointLonEnc < rectLonMaxEnc;
|
||||||
|
} else {
|
||||||
|
// Rect crosses dateline:
|
||||||
|
return pointLatEnc >= rectLatMinEnc &&
|
||||||
|
pointLatEnc < rectLatMaxEnc &&
|
||||||
|
(pointLonEnc >= rectLonMinEnc ||
|
||||||
|
pointLonEnc < rectLonMaxEnc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double randomLat() {
|
private static double randomLat() {
|
||||||
|
|
Loading…
Reference in New Issue