mirror of https://github.com/apache/lucene.git
LUCENE-7221: Limit the number of requests to getRelationship() and isWithin() using bounds.
This commit is contained in:
parent
d34dc47c82
commit
0b0e442010
|
@ -21,6 +21,7 @@ import java.io.IOException;
|
||||||
import org.apache.lucene.spatial3d.geom.BasePlanetObject;
|
import org.apache.lucene.spatial3d.geom.BasePlanetObject;
|
||||||
import org.apache.lucene.spatial3d.geom.GeoShape;
|
import org.apache.lucene.spatial3d.geom.GeoShape;
|
||||||
import org.apache.lucene.spatial3d.geom.PlanetModel;
|
import org.apache.lucene.spatial3d.geom.PlanetModel;
|
||||||
|
import org.apache.lucene.spatial3d.geom.XYZBounds;
|
||||||
import org.apache.lucene.index.PointValues;
|
import org.apache.lucene.index.PointValues;
|
||||||
import org.apache.lucene.index.LeafReader;
|
import org.apache.lucene.index.LeafReader;
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
|
@ -41,11 +42,14 @@ import org.apache.lucene.util.DocIdSetBuilder;
|
||||||
final class PointInGeo3DShapeQuery extends Query {
|
final class PointInGeo3DShapeQuery extends Query {
|
||||||
final String field;
|
final String field;
|
||||||
final GeoShape shape;
|
final GeoShape shape;
|
||||||
|
final XYZBounds shapeBounds;
|
||||||
|
|
||||||
/** The lats/lons must be clockwise or counter-clockwise. */
|
/** The lats/lons must be clockwise or counter-clockwise. */
|
||||||
public PointInGeo3DShapeQuery(String field, GeoShape shape) {
|
public PointInGeo3DShapeQuery(String field, GeoShape shape) {
|
||||||
this.field = field;
|
this.field = field;
|
||||||
this.shape = shape;
|
this.shape = shape;
|
||||||
|
this.shapeBounds = new XYZBounds();
|
||||||
|
shape.getBounds(shapeBounds);
|
||||||
|
|
||||||
if (shape instanceof BasePlanetObject) {
|
if (shape instanceof BasePlanetObject) {
|
||||||
BasePlanetObject planetObject = (BasePlanetObject) shape;
|
BasePlanetObject planetObject = (BasePlanetObject) shape;
|
||||||
|
@ -95,7 +99,7 @@ final class PointInGeo3DShapeQuery extends Query {
|
||||||
|
|
||||||
DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc());
|
DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc());
|
||||||
|
|
||||||
values.intersect(field, new PointInShapeIntersectVisitor(result, shape));
|
values.intersect(field, new PointInShapeIntersectVisitor(result, shape, shapeBounds));
|
||||||
|
|
||||||
return new ConstantScoreScorer(this, score(), result.build().iterator());
|
return new ConstantScoreScorer(this, score(), result.build().iterator());
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,16 +23,19 @@ import org.apache.lucene.spatial3d.geom.GeoArea;
|
||||||
import org.apache.lucene.spatial3d.geom.GeoAreaFactory;
|
import org.apache.lucene.spatial3d.geom.GeoAreaFactory;
|
||||||
import org.apache.lucene.spatial3d.geom.GeoShape;
|
import org.apache.lucene.spatial3d.geom.GeoShape;
|
||||||
import org.apache.lucene.spatial3d.geom.PlanetModel;
|
import org.apache.lucene.spatial3d.geom.PlanetModel;
|
||||||
|
import org.apache.lucene.spatial3d.geom.XYZBounds;
|
||||||
import org.apache.lucene.util.DocIdSetBuilder;
|
import org.apache.lucene.util.DocIdSetBuilder;
|
||||||
import org.apache.lucene.util.NumericUtils;
|
import org.apache.lucene.util.NumericUtils;
|
||||||
|
|
||||||
class PointInShapeIntersectVisitor implements IntersectVisitor {
|
class PointInShapeIntersectVisitor implements IntersectVisitor {
|
||||||
private final DocIdSetBuilder hits;
|
private final DocIdSetBuilder hits;
|
||||||
private final GeoShape shape;
|
private final GeoShape shape;
|
||||||
|
private final XYZBounds shapeBounds;
|
||||||
|
|
||||||
public PointInShapeIntersectVisitor(DocIdSetBuilder hits, GeoShape shape) {
|
public PointInShapeIntersectVisitor(DocIdSetBuilder hits, GeoShape shape, XYZBounds shapeBounds) {
|
||||||
this.hits = hits;
|
this.hits = hits;
|
||||||
this.shape = shape;
|
this.shape = shape;
|
||||||
|
this.shapeBounds = shapeBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -46,10 +49,14 @@ class PointInShapeIntersectVisitor implements IntersectVisitor {
|
||||||
double x = Geo3DPoint.decodeDimension(packedValue, 0);
|
double x = Geo3DPoint.decodeDimension(packedValue, 0);
|
||||||
double y = Geo3DPoint.decodeDimension(packedValue, Integer.BYTES);
|
double y = Geo3DPoint.decodeDimension(packedValue, Integer.BYTES);
|
||||||
double z = Geo3DPoint.decodeDimension(packedValue, 2 * Integer.BYTES);
|
double z = Geo3DPoint.decodeDimension(packedValue, 2 * Integer.BYTES);
|
||||||
|
if (x >= shapeBounds.getMinimumX() && x <= shapeBounds.getMaximumX() &&
|
||||||
|
y >= shapeBounds.getMinimumY() && y <= shapeBounds.getMaximumY() &&
|
||||||
|
z >= shapeBounds.getMinimumZ() && z <= shapeBounds.getMaximumZ()) {
|
||||||
if (shape.isWithin(x, y, z)) {
|
if (shape.isWithin(x, y, z)) {
|
||||||
hits.add(docID);
|
hits.add(docID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
|
public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
|
||||||
|
@ -69,6 +76,14 @@ class PointInShapeIntersectVisitor implements IntersectVisitor {
|
||||||
assert yMin <= yMax;
|
assert yMin <= yMax;
|
||||||
assert zMin <= zMax;
|
assert zMin <= zMax;
|
||||||
|
|
||||||
|
// First, check bounds. If the shape is entirely contained, return CELL_CROSSES_QUERY.
|
||||||
|
if (shapeBounds.getMinimumX() >= xMin && shapeBounds.getMaximumX() <= xMax &&
|
||||||
|
shapeBounds.getMinimumY() >= yMin && shapeBounds.getMaximumY() <= yMax &&
|
||||||
|
shapeBounds.getMinimumZ() >= zMin && shapeBounds.getMaximumZ() <= zMax) {
|
||||||
|
return Relation.CELL_CROSSES_QUERY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quick test failed so do slower one...
|
||||||
GeoArea xyzSolid = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84, xMin, xMax, yMin, yMax, zMin, zMax);
|
GeoArea xyzSolid = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84, xMin, xMax, yMin, yMax, zMin, zMax);
|
||||||
|
|
||||||
switch(xyzSolid.getRelationship(shape)) {
|
switch(xyzSolid.getRelationship(shape)) {
|
||||||
|
|
Loading…
Reference in New Issue