Query DSL: Make geo filters queries.
This commit replaces geo filters with queries that support two-phase iteration.
This commit is contained in:
parent
842608c396
commit
f22935b1a8
|
@ -1,216 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to Elasticsearch under one or more contributor
|
|
||||||
* license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright
|
|
||||||
* ownership. Elasticsearch 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.elasticsearch.common.lucene.docset;
|
|
||||||
|
|
||||||
import org.apache.lucene.search.DocIdSet;
|
|
||||||
import org.apache.lucene.search.DocIdSetIterator;
|
|
||||||
import org.apache.lucene.util.ArrayUtil;
|
|
||||||
import org.apache.lucene.util.BitSet;
|
|
||||||
import org.apache.lucene.util.Bits;
|
|
||||||
import org.apache.lucene.util.InPlaceMergeSorter;
|
|
||||||
import org.apache.lucene.util.RamUsageEstimator;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class AndDocIdSet extends DocIdSet {
|
|
||||||
|
|
||||||
private final DocIdSet[] sets;
|
|
||||||
|
|
||||||
public AndDocIdSet(DocIdSet[] sets) {
|
|
||||||
this.sets = sets;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCacheable() {
|
|
||||||
for (DocIdSet set : sets) {
|
|
||||||
if (!set.isCacheable()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long ramBytesUsed() {
|
|
||||||
long ramBytesUsed = RamUsageEstimator.NUM_BYTES_OBJECT_REF + RamUsageEstimator.NUM_BYTES_ARRAY_HEADER;
|
|
||||||
for (DocIdSet set : sets) {
|
|
||||||
ramBytesUsed += RamUsageEstimator.NUM_BYTES_OBJECT_REF + set.ramBytesUsed();
|
|
||||||
}
|
|
||||||
return ramBytesUsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Bits bits() throws IOException {
|
|
||||||
Bits[] bits = new Bits[sets.length];
|
|
||||||
for (int i = 0; i < sets.length; i++) {
|
|
||||||
bits[i] = sets[i].bits();
|
|
||||||
if (bits[i] == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new AndBits(bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DocIdSetIterator iterator() throws IOException {
|
|
||||||
// we try and be smart here, if we can iterate through docsets quickly, prefer to iterate
|
|
||||||
// over them as much as possible, before actually going to "bits" based ones to check
|
|
||||||
List<DocIdSetIterator> iterators = new ArrayList<>(sets.length);
|
|
||||||
List<Bits> bits = new ArrayList<>(sets.length);
|
|
||||||
for (DocIdSet set : sets) {
|
|
||||||
if (DocIdSets.isEmpty(set)) {
|
|
||||||
return DocIdSetIterator.empty();
|
|
||||||
}
|
|
||||||
DocIdSetIterator it = set.iterator();
|
|
||||||
if (it == null) {
|
|
||||||
return DocIdSetIterator.empty();
|
|
||||||
}
|
|
||||||
Bits bit = set.bits();
|
|
||||||
if (bit != null && bit instanceof BitSet == false) {
|
|
||||||
bits.add(bit);
|
|
||||||
} else {
|
|
||||||
iterators.add(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (bits.isEmpty()) {
|
|
||||||
return IteratorBasedIterator.newDocIdSetIterator(iterators);
|
|
||||||
}
|
|
||||||
if (iterators.isEmpty()) {
|
|
||||||
return new BitsDocIdSetIterator(new AndBits(bits.toArray(new Bits[bits.size()])));
|
|
||||||
}
|
|
||||||
// combination of both..., first iterating over the "fast" ones, and then checking on the more
|
|
||||||
// expensive ones
|
|
||||||
return new BitsDocIdSetIterator.FilteredIterator(
|
|
||||||
IteratorBasedIterator.newDocIdSetIterator(iterators),
|
|
||||||
new AndBits(bits.toArray(new Bits[bits.size()]))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A conjunction between several {@link Bits} instances with short-circuit logic. */
|
|
||||||
public static class AndBits implements Bits {
|
|
||||||
|
|
||||||
private final Bits[] bits;
|
|
||||||
|
|
||||||
public AndBits(Bits[] bits) {
|
|
||||||
this.bits = bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean get(int index) {
|
|
||||||
for (Bits bit : bits) {
|
|
||||||
if (!bit.get(index)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int length() {
|
|
||||||
return bits[0].length();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class IteratorBasedIterator extends DocIdSetIterator {
|
|
||||||
private int doc = -1;
|
|
||||||
private final DocIdSetIterator lead;
|
|
||||||
private final DocIdSetIterator[] otherIterators;
|
|
||||||
|
|
||||||
|
|
||||||
public static DocIdSetIterator newDocIdSetIterator(Collection<DocIdSetIterator> iterators) throws IOException {
|
|
||||||
if (iterators.isEmpty()) {
|
|
||||||
return DocIdSetIterator.empty();
|
|
||||||
}
|
|
||||||
if (iterators.size() == 1) {
|
|
||||||
// shortcut if there is only one valid iterator.
|
|
||||||
return iterators.iterator().next();
|
|
||||||
}
|
|
||||||
return new IteratorBasedIterator(iterators);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IteratorBasedIterator(Collection<DocIdSetIterator> iterators) throws IOException {
|
|
||||||
final DocIdSetIterator[] sortedIterators = iterators.toArray(new DocIdSetIterator[iterators.size()]);
|
|
||||||
new InPlaceMergeSorter() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int compare(int i, int j) {
|
|
||||||
return Long.compare(sortedIterators[i].cost(), sortedIterators[j].cost());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void swap(int i, int j) {
|
|
||||||
ArrayUtil.swap(sortedIterators, i, j);
|
|
||||||
}
|
|
||||||
|
|
||||||
}.sort(0, sortedIterators.length);
|
|
||||||
lead = sortedIterators[0];
|
|
||||||
this.otherIterators = Arrays.copyOfRange(sortedIterators, 1, sortedIterators.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final int docID() {
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final int nextDoc() throws IOException {
|
|
||||||
doc = lead.nextDoc();
|
|
||||||
return doNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final int advance(int target) throws IOException {
|
|
||||||
doc = lead.advance(target);
|
|
||||||
return doNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
private int doNext() throws IOException {
|
|
||||||
main:
|
|
||||||
while (true) {
|
|
||||||
for (DocIdSetIterator otherIterator : otherIterators) {
|
|
||||||
// the following assert is the invariant of the loop
|
|
||||||
assert otherIterator.docID() <= doc;
|
|
||||||
// the current doc might already be equal to doc if it broke the loop
|
|
||||||
// at the previous iteration
|
|
||||||
if (otherIterator.docID() < doc) {
|
|
||||||
final int advanced = otherIterator.advance(doc);
|
|
||||||
if (advanced > doc) {
|
|
||||||
doc = lead.advance(advanced);
|
|
||||||
continue main;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long cost() {
|
|
||||||
return lead.cost();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -29,8 +29,8 @@ import org.elasticsearch.index.fielddata.IndexGeoPointFieldData;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
||||||
import org.elasticsearch.index.search.geo.InMemoryGeoBoundingBoxFilter;
|
import org.elasticsearch.index.search.geo.InMemoryGeoBoundingBoxQuery;
|
||||||
import org.elasticsearch.index.search.geo.IndexedGeoBoundingBoxFilter;
|
import org.elasticsearch.index.search.geo.IndexedGeoBoundingBoxQuery;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -173,10 +173,10 @@ public class GeoBoundingBoxQueryParser implements QueryParser {
|
||||||
|
|
||||||
Query filter;
|
Query filter;
|
||||||
if ("indexed".equals(type)) {
|
if ("indexed".equals(type)) {
|
||||||
filter = IndexedGeoBoundingBoxFilter.create(topLeft, bottomRight, geoMapper);
|
filter = IndexedGeoBoundingBoxQuery.create(topLeft, bottomRight, geoMapper);
|
||||||
} else if ("memory".equals(type)) {
|
} else if ("memory".equals(type)) {
|
||||||
IndexGeoPointFieldData indexFieldData = parseContext.getForField(mapper);
|
IndexGeoPointFieldData indexFieldData = parseContext.getForField(mapper);
|
||||||
filter = new InMemoryGeoBoundingBoxFilter(topLeft, bottomRight, indexFieldData);
|
filter = new InMemoryGeoBoundingBoxQuery(topLeft, bottomRight, indexFieldData);
|
||||||
} else {
|
} else {
|
||||||
throw new QueryParsingException(parseContext, "geo bounding box type [" + type
|
throw new QueryParsingException(parseContext, "geo bounding box type [" + type
|
||||||
+ "] not supported, either 'indexed' or 'memory' are allowed");
|
+ "] not supported, either 'indexed' or 'memory' are allowed");
|
||||||
|
|
|
@ -31,7 +31,7 @@ import org.elasticsearch.index.fielddata.IndexGeoPointFieldData;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
||||||
import org.elasticsearch.index.search.geo.GeoDistanceFilter;
|
import org.elasticsearch.index.search.geo.GeoDistanceRangeQuery;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ public class GeoDistanceQueryParser implements QueryParser {
|
||||||
|
|
||||||
|
|
||||||
IndexGeoPointFieldData indexFieldData = parseContext.getForField(mapper);
|
IndexGeoPointFieldData indexFieldData = parseContext.getForField(mapper);
|
||||||
Query query = new GeoDistanceFilter(point.lat(), point.lon(), distance, geoDistance, indexFieldData, geoMapper, optimizeBbox);
|
Query query = new GeoDistanceRangeQuery(point, null, distance, true, false, geoDistance, geoMapper, indexFieldData, optimizeBbox);
|
||||||
if (queryName != null) {
|
if (queryName != null) {
|
||||||
parseContext.addNamedQuery(queryName, query);
|
parseContext.addNamedQuery(queryName, query);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ import org.elasticsearch.index.fielddata.IndexGeoPointFieldData;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
||||||
import org.elasticsearch.index.search.geo.GeoDistanceRangeFilter;
|
import org.elasticsearch.index.search.geo.GeoDistanceRangeQuery;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ public class GeoDistanceRangeQueryParser implements QueryParser {
|
||||||
GeoPointFieldMapper geoMapper = ((GeoPointFieldMapper) mapper);
|
GeoPointFieldMapper geoMapper = ((GeoPointFieldMapper) mapper);
|
||||||
|
|
||||||
IndexGeoPointFieldData indexFieldData = parseContext.getForField(mapper);
|
IndexGeoPointFieldData indexFieldData = parseContext.getForField(mapper);
|
||||||
Query query = new GeoDistanceRangeFilter(point, from, to, includeLower, includeUpper, geoDistance, geoMapper, indexFieldData, optimizeBbox);
|
Query query = new GeoDistanceRangeQuery(point, from, to, includeLower, includeUpper, geoDistance, geoMapper, indexFieldData, optimizeBbox);
|
||||||
if (queryName != null) {
|
if (queryName != null) {
|
||||||
parseContext.addNamedQuery(queryName, query);
|
parseContext.addNamedQuery(queryName, query);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ import org.elasticsearch.index.fielddata.IndexGeoPointFieldData;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
||||||
import org.elasticsearch.index.search.geo.GeoPolygonFilter;
|
import org.elasticsearch.index.search.geo.GeoPolygonQuery;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -147,7 +147,7 @@ public class GeoPolygonQueryParser implements QueryParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexGeoPointFieldData indexFieldData = parseContext.getForField(mapper);
|
IndexGeoPointFieldData indexFieldData = parseContext.getForField(mapper);
|
||||||
Query query = new GeoPolygonFilter(indexFieldData, shell.toArray(new GeoPoint[shell.size()]));
|
Query query = new GeoPolygonQuery(indexFieldData, shell.toArray(new GeoPoint[shell.size()]));
|
||||||
if (queryName != null) {
|
if (queryName != null) {
|
||||||
parseContext.addNamedQuery(queryName, query);
|
parseContext.addNamedQuery(queryName, query);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,191 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to Elasticsearch under one or more contributor
|
|
||||||
* license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright
|
|
||||||
* ownership. Elasticsearch 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.elasticsearch.index.search.geo;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
|
||||||
import org.apache.lucene.search.DocIdSet;
|
|
||||||
import org.apache.lucene.search.DocValuesDocIdSet;
|
|
||||||
import org.apache.lucene.search.Filter;
|
|
||||||
import org.apache.lucene.util.Bits;
|
|
||||||
import org.elasticsearch.common.Nullable;
|
|
||||||
import org.elasticsearch.common.geo.GeoDistance;
|
|
||||||
import org.elasticsearch.common.geo.GeoPoint;
|
|
||||||
import org.elasticsearch.common.lucene.docset.AndDocIdSet;
|
|
||||||
import org.elasticsearch.common.lucene.docset.DocIdSets;
|
|
||||||
import org.elasticsearch.common.unit.DistanceUnit;
|
|
||||||
import org.elasticsearch.index.fielddata.IndexGeoPointFieldData;
|
|
||||||
import org.elasticsearch.index.fielddata.MultiGeoPointValues;
|
|
||||||
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
public class GeoDistanceFilter extends Filter {
|
|
||||||
|
|
||||||
private final double lat;
|
|
||||||
|
|
||||||
private final double lon;
|
|
||||||
|
|
||||||
private final double distance; // in miles
|
|
||||||
|
|
||||||
private final GeoDistance geoDistance;
|
|
||||||
|
|
||||||
private final IndexGeoPointFieldData indexFieldData;
|
|
||||||
|
|
||||||
private final GeoDistance.FixedSourceDistance fixedSourceDistance;
|
|
||||||
private final GeoDistance.DistanceBoundingCheck distanceBoundingCheck;
|
|
||||||
private final Filter boundingBoxFilter;
|
|
||||||
|
|
||||||
public GeoDistanceFilter(double lat, double lon, double distance, GeoDistance geoDistance, IndexGeoPointFieldData indexFieldData, GeoPointFieldMapper mapper,
|
|
||||||
String optimizeBbox) {
|
|
||||||
this.lat = lat;
|
|
||||||
this.lon = lon;
|
|
||||||
this.distance = distance;
|
|
||||||
this.geoDistance = geoDistance;
|
|
||||||
this.indexFieldData = indexFieldData;
|
|
||||||
|
|
||||||
this.fixedSourceDistance = geoDistance.fixedSourceDistance(lat, lon, DistanceUnit.DEFAULT);
|
|
||||||
GeoDistance.DistanceBoundingCheck distanceBoundingCheck = null;
|
|
||||||
if (optimizeBbox != null && !"none".equals(optimizeBbox)) {
|
|
||||||
distanceBoundingCheck = GeoDistance.distanceBoundingCheck(lat, lon, distance, DistanceUnit.DEFAULT);
|
|
||||||
if ("memory".equals(optimizeBbox)) {
|
|
||||||
boundingBoxFilter = null;
|
|
||||||
} else if ("indexed".equals(optimizeBbox)) {
|
|
||||||
boundingBoxFilter = IndexedGeoBoundingBoxFilter.create(distanceBoundingCheck.topLeft(), distanceBoundingCheck.bottomRight(), mapper);
|
|
||||||
distanceBoundingCheck = GeoDistance.ALWAYS_INSTANCE; // fine, we do the bounding box check using the filter
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("type [" + optimizeBbox + "] for bounding box optimization not supported");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
distanceBoundingCheck = GeoDistance.ALWAYS_INSTANCE;
|
|
||||||
boundingBoxFilter = null;
|
|
||||||
}
|
|
||||||
this.distanceBoundingCheck = distanceBoundingCheck;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double lat() {
|
|
||||||
return lat;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double lon() {
|
|
||||||
return lon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double distance() {
|
|
||||||
return distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GeoDistance geoDistance() {
|
|
||||||
return geoDistance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String fieldName() {
|
|
||||||
return indexFieldData.getFieldNames().indexName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptedDocs) throws IOException {
|
|
||||||
DocIdSet boundingBoxDocSet = null;
|
|
||||||
if (boundingBoxFilter != null) {
|
|
||||||
boundingBoxDocSet = boundingBoxFilter.getDocIdSet(context, null);
|
|
||||||
if (DocIdSets.isEmpty(boundingBoxDocSet)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
final MultiGeoPointValues values = indexFieldData.load(context).getGeoPointValues();
|
|
||||||
GeoDistanceDocSet distDocSet = new GeoDistanceDocSet(context.reader().maxDoc(), acceptedDocs, values, fixedSourceDistance, distanceBoundingCheck, distance);
|
|
||||||
if (boundingBoxDocSet == null) {
|
|
||||||
return distDocSet;
|
|
||||||
} else {
|
|
||||||
return new AndDocIdSet(new DocIdSet[]{boundingBoxDocSet, distDocSet});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (super.equals(o) == false) return false;
|
|
||||||
|
|
||||||
GeoDistanceFilter filter = (GeoDistanceFilter) o;
|
|
||||||
|
|
||||||
if (Double.compare(filter.distance, distance) != 0) return false;
|
|
||||||
if (Double.compare(filter.lat, lat) != 0) return false;
|
|
||||||
if (Double.compare(filter.lon, lon) != 0) return false;
|
|
||||||
if (!indexFieldData.getFieldNames().indexName().equals(filter.indexFieldData.getFieldNames().indexName()))
|
|
||||||
return false;
|
|
||||||
if (geoDistance != filter.geoDistance) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString(String field) {
|
|
||||||
return "GeoDistanceFilter(" + indexFieldData.getFieldNames().indexName() + ", " + geoDistance + ", " + distance + ", " + lat + ", " + lon + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = super.hashCode();
|
|
||||||
long temp;
|
|
||||||
temp = lat != +0.0d ? Double.doubleToLongBits(lat) : 0L;
|
|
||||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
|
||||||
temp = lon != +0.0d ? Double.doubleToLongBits(lon) : 0L;
|
|
||||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
|
||||||
temp = distance != +0.0d ? Double.doubleToLongBits(distance) : 0L;
|
|
||||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
|
||||||
result = 31 * result + (geoDistance != null ? geoDistance.hashCode() : 0);
|
|
||||||
result = 31 * result + indexFieldData.getFieldNames().indexName().hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class GeoDistanceDocSet extends DocValuesDocIdSet {
|
|
||||||
private final double distance; // in miles
|
|
||||||
private final MultiGeoPointValues values;
|
|
||||||
private final GeoDistance.FixedSourceDistance fixedSourceDistance;
|
|
||||||
private final GeoDistance.DistanceBoundingCheck distanceBoundingCheck;
|
|
||||||
|
|
||||||
public GeoDistanceDocSet(int maxDoc, @Nullable Bits acceptDocs, MultiGeoPointValues values, GeoDistance.FixedSourceDistance fixedSourceDistance, GeoDistance.DistanceBoundingCheck distanceBoundingCheck,
|
|
||||||
double distance) {
|
|
||||||
super(maxDoc, acceptDocs);
|
|
||||||
this.values = values;
|
|
||||||
this.fixedSourceDistance = fixedSourceDistance;
|
|
||||||
this.distanceBoundingCheck = distanceBoundingCheck;
|
|
||||||
this.distance = distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean matchDoc(int doc) {
|
|
||||||
|
|
||||||
values.setDocument(doc);
|
|
||||||
final int length = values.count();
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
GeoPoint point = values.valueAt(i);
|
|
||||||
if (distanceBoundingCheck.isWithin(point.lat(), point.lon())) {
|
|
||||||
double d = fixedSourceDistance.calculate(point.lat(), point.lon());
|
|
||||||
if (d < distance) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,28 +19,30 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.search.geo;
|
package org.elasticsearch.index.search.geo;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
import org.apache.lucene.search.DocIdSet;
|
import org.apache.lucene.search.ConstantScoreScorer;
|
||||||
import org.apache.lucene.search.DocValuesDocIdSet;
|
import org.apache.lucene.search.ConstantScoreWeight;
|
||||||
import org.apache.lucene.search.Filter;
|
import org.apache.lucene.search.DocIdSetIterator;
|
||||||
|
import org.apache.lucene.search.IndexSearcher;
|
||||||
|
import org.apache.lucene.search.Query;
|
||||||
|
import org.apache.lucene.search.Scorer;
|
||||||
|
import org.apache.lucene.search.TwoPhaseIterator;
|
||||||
|
import org.apache.lucene.search.Weight;
|
||||||
import org.apache.lucene.util.Bits;
|
import org.apache.lucene.util.Bits;
|
||||||
import org.apache.lucene.util.NumericUtils;
|
import org.apache.lucene.util.NumericUtils;
|
||||||
import org.elasticsearch.common.Nullable;
|
|
||||||
import org.elasticsearch.common.geo.GeoDistance;
|
import org.elasticsearch.common.geo.GeoDistance;
|
||||||
import org.elasticsearch.common.geo.GeoPoint;
|
import org.elasticsearch.common.geo.GeoPoint;
|
||||||
import org.elasticsearch.common.lucene.docset.AndDocIdSet;
|
|
||||||
import org.elasticsearch.common.lucene.docset.DocIdSets;
|
|
||||||
import org.elasticsearch.common.unit.DistanceUnit;
|
import org.elasticsearch.common.unit.DistanceUnit;
|
||||||
import org.elasticsearch.index.fielddata.IndexGeoPointFieldData;
|
import org.elasticsearch.index.fielddata.IndexGeoPointFieldData;
|
||||||
import org.elasticsearch.index.fielddata.MultiGeoPointValues;
|
import org.elasticsearch.index.fielddata.MultiGeoPointValues;
|
||||||
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class GeoDistanceRangeFilter extends Filter {
|
public class GeoDistanceRangeQuery extends Query {
|
||||||
|
|
||||||
private final double lat;
|
private final double lat;
|
||||||
private final double lon;
|
private final double lon;
|
||||||
|
@ -51,11 +53,11 @@ public class GeoDistanceRangeFilter extends Filter {
|
||||||
private final GeoDistance geoDistance;
|
private final GeoDistance geoDistance;
|
||||||
private final GeoDistance.FixedSourceDistance fixedSourceDistance;
|
private final GeoDistance.FixedSourceDistance fixedSourceDistance;
|
||||||
private GeoDistance.DistanceBoundingCheck distanceBoundingCheck;
|
private GeoDistance.DistanceBoundingCheck distanceBoundingCheck;
|
||||||
private final Filter boundingBoxFilter;
|
private final Query boundingBoxFilter;
|
||||||
|
|
||||||
private final IndexGeoPointFieldData indexFieldData;
|
private final IndexGeoPointFieldData indexFieldData;
|
||||||
|
|
||||||
public GeoDistanceRangeFilter(GeoPoint point, Double lowerVal, Double upperVal, boolean includeLower, boolean includeUpper, GeoDistance geoDistance, GeoPointFieldMapper mapper, IndexGeoPointFieldData indexFieldData,
|
public GeoDistanceRangeQuery(GeoPoint point, Double lowerVal, Double upperVal, boolean includeLower, boolean includeUpper, GeoDistance geoDistance, GeoPointFieldMapper mapper, IndexGeoPointFieldData indexFieldData,
|
||||||
String optimizeBbox) {
|
String optimizeBbox) {
|
||||||
this.lat = point.lat();
|
this.lat = point.lat();
|
||||||
this.lon = point.lon();
|
this.lon = point.lon();
|
||||||
|
@ -88,7 +90,7 @@ public class GeoDistanceRangeFilter extends Filter {
|
||||||
if ("memory".equals(optimizeBbox)) {
|
if ("memory".equals(optimizeBbox)) {
|
||||||
boundingBoxFilter = null;
|
boundingBoxFilter = null;
|
||||||
} else if ("indexed".equals(optimizeBbox)) {
|
} else if ("indexed".equals(optimizeBbox)) {
|
||||||
boundingBoxFilter = IndexedGeoBoundingBoxFilter.create(distanceBoundingCheck.topLeft(), distanceBoundingCheck.bottomRight(), mapper);
|
boundingBoxFilter = IndexedGeoBoundingBoxQuery.create(distanceBoundingCheck.topLeft(), distanceBoundingCheck.bottomRight(), mapper);
|
||||||
distanceBoundingCheck = GeoDistance.ALWAYS_INSTANCE; // fine, we do the bounding box check using the filter
|
distanceBoundingCheck = GeoDistance.ALWAYS_INSTANCE; // fine, we do the bounding box check using the filter
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("type [" + optimizeBbox + "] for bounding box optimization not supported");
|
throw new IllegalArgumentException("type [" + optimizeBbox + "] for bounding box optimization not supported");
|
||||||
|
@ -111,30 +113,72 @@ public class GeoDistanceRangeFilter extends Filter {
|
||||||
return geoDistance;
|
return geoDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double minInclusiveDistance() {
|
||||||
|
return inclusiveLowerPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double maxInclusiveDistance() {
|
||||||
|
return inclusiveUpperPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String fieldName() {
|
||||||
|
return indexFieldData.getFieldNames().indexName();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptedDocs) throws IOException {
|
public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
|
||||||
DocIdSet boundingBoxDocSet = null;
|
final Weight boundingBoxWeight;
|
||||||
if (boundingBoxFilter != null) {
|
if (boundingBoxFilter != null) {
|
||||||
boundingBoxDocSet = boundingBoxFilter.getDocIdSet(context, null);
|
boundingBoxWeight = boundingBoxFilter.createWeight(searcher, false);
|
||||||
if (DocIdSets.isEmpty(boundingBoxDocSet)) {
|
} else {
|
||||||
|
boundingBoxWeight = null;
|
||||||
|
}
|
||||||
|
return new ConstantScoreWeight(this) {
|
||||||
|
@Override
|
||||||
|
public Scorer scorer(LeafReaderContext context, final Bits acceptDocs) throws IOException {
|
||||||
|
final DocIdSetIterator approximation;
|
||||||
|
if (boundingBoxWeight != null) {
|
||||||
|
approximation = boundingBoxWeight.scorer(context, null);
|
||||||
|
} else {
|
||||||
|
approximation = DocIdSetIterator.all(context.reader().maxDoc());
|
||||||
|
}
|
||||||
|
if (approximation == null) {
|
||||||
|
// if the approximation does not match anything, we're done
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
final MultiGeoPointValues values = indexFieldData.load(context).getGeoPointValues();
|
||||||
|
final TwoPhaseIterator twoPhaseIterator = new TwoPhaseIterator(approximation) {
|
||||||
|
@Override
|
||||||
|
public boolean matches() throws IOException {
|
||||||
|
final int doc = approximation.docID();
|
||||||
|
if (acceptDocs != null && acceptDocs.get(doc) == false) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
MultiGeoPointValues values = indexFieldData.load(context).getGeoPointValues();
|
values.setDocument(doc);
|
||||||
GeoDistanceRangeDocSet distDocSet = new GeoDistanceRangeDocSet(context.reader().maxDoc(), acceptedDocs, values, fixedSourceDistance, distanceBoundingCheck, inclusiveLowerPoint, inclusiveUpperPoint);
|
final int length = values.count();
|
||||||
if (boundingBoxDocSet == null) {
|
for (int i = 0; i < length; i++) {
|
||||||
return distDocSet;
|
GeoPoint point = values.valueAt(i);
|
||||||
} else {
|
if (distanceBoundingCheck.isWithin(point.lat(), point.lon())) {
|
||||||
return new AndDocIdSet(new DocIdSet[]{boundingBoxDocSet, distDocSet});
|
double d = fixedSourceDistance.calculate(point.lat(), point.lon());
|
||||||
|
if (d >= inclusiveLowerPoint && d <= inclusiveUpperPoint) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return new ConstantScoreScorer(this, score(), twoPhaseIterator);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (super.equals(o) == false) return false;
|
if (super.equals(o) == false) return false;
|
||||||
|
|
||||||
GeoDistanceRangeFilter filter = (GeoDistanceRangeFilter) o;
|
GeoDistanceRangeQuery filter = (GeoDistanceRangeQuery) o;
|
||||||
|
|
||||||
if (Double.compare(filter.inclusiveLowerPoint, inclusiveLowerPoint) != 0) return false;
|
if (Double.compare(filter.inclusiveLowerPoint, inclusiveLowerPoint) != 0) return false;
|
||||||
if (Double.compare(filter.inclusiveUpperPoint, inclusiveUpperPoint) != 0) return false;
|
if (Double.compare(filter.inclusiveUpperPoint, inclusiveUpperPoint) != 0) return false;
|
||||||
|
@ -169,38 +213,4 @@ public class GeoDistanceRangeFilter extends Filter {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class GeoDistanceRangeDocSet extends DocValuesDocIdSet {
|
|
||||||
|
|
||||||
private final MultiGeoPointValues values;
|
|
||||||
private final GeoDistance.FixedSourceDistance fixedSourceDistance;
|
|
||||||
private final GeoDistance.DistanceBoundingCheck distanceBoundingCheck;
|
|
||||||
private final double inclusiveLowerPoint; // in miles
|
|
||||||
private final double inclusiveUpperPoint; // in miles
|
|
||||||
|
|
||||||
public GeoDistanceRangeDocSet(int maxDoc, @Nullable Bits acceptDocs, MultiGeoPointValues values, GeoDistance.FixedSourceDistance fixedSourceDistance, GeoDistance.DistanceBoundingCheck distanceBoundingCheck,
|
|
||||||
double inclusiveLowerPoint, double inclusiveUpperPoint) {
|
|
||||||
super(maxDoc, acceptDocs);
|
|
||||||
this.values = values;
|
|
||||||
this.fixedSourceDistance = fixedSourceDistance;
|
|
||||||
this.distanceBoundingCheck = distanceBoundingCheck;
|
|
||||||
this.inclusiveLowerPoint = inclusiveLowerPoint;
|
|
||||||
this.inclusiveUpperPoint = inclusiveUpperPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean matchDoc(int doc) {
|
|
||||||
values.setDocument(doc);
|
|
||||||
final int length = values.count();
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
GeoPoint point = values.valueAt(i);
|
|
||||||
if (distanceBoundingCheck.isWithin(point.lat(), point.lon())) {
|
|
||||||
double d = fixedSourceDistance.calculate(point.lat(), point.lon());
|
|
||||||
if (d >= inclusiveLowerPoint && d <= inclusiveUpperPoint) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,109 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to Elasticsearch under one or more contributor
|
|
||||||
* license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright
|
|
||||||
* ownership. Elasticsearch 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.elasticsearch.index.search.geo;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
|
||||||
import org.apache.lucene.search.DocIdSet;
|
|
||||||
import org.apache.lucene.search.DocValuesDocIdSet;
|
|
||||||
import org.apache.lucene.search.Filter;
|
|
||||||
import org.apache.lucene.util.Bits;
|
|
||||||
import org.elasticsearch.common.Nullable;
|
|
||||||
import org.elasticsearch.common.geo.GeoPoint;
|
|
||||||
import org.elasticsearch.index.fielddata.IndexGeoPointFieldData;
|
|
||||||
import org.elasticsearch.index.fielddata.MultiGeoPointValues;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class GeoPolygonFilter extends Filter {
|
|
||||||
|
|
||||||
private final GeoPoint[] points;
|
|
||||||
|
|
||||||
private final IndexGeoPointFieldData indexFieldData;
|
|
||||||
|
|
||||||
public GeoPolygonFilter(IndexGeoPointFieldData indexFieldData, GeoPoint...points) {
|
|
||||||
this.points = points;
|
|
||||||
this.indexFieldData = indexFieldData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GeoPoint[] points() {
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String fieldName() {
|
|
||||||
return indexFieldData.getFieldNames().indexName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptedDocs) throws IOException {
|
|
||||||
final MultiGeoPointValues values = indexFieldData.load(context).getGeoPointValues();
|
|
||||||
return new GeoPolygonDocIdSet(context.reader().maxDoc(), acceptedDocs, values, points);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString(String field) {
|
|
||||||
StringBuilder sb = new StringBuilder("GeoPolygonFilter(");
|
|
||||||
sb.append(indexFieldData.getFieldNames().indexName());
|
|
||||||
sb.append(", ").append(Arrays.toString(points)).append(')');
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class GeoPolygonDocIdSet extends DocValuesDocIdSet {
|
|
||||||
private final MultiGeoPointValues values;
|
|
||||||
private final GeoPoint[] points;
|
|
||||||
|
|
||||||
public GeoPolygonDocIdSet(int maxDoc, @Nullable Bits acceptDocs, MultiGeoPointValues values, GeoPoint[] points) {
|
|
||||||
super(maxDoc, acceptDocs);
|
|
||||||
this.values = values;
|
|
||||||
this.points = points;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean matchDoc(int doc) {
|
|
||||||
values.setDocument(doc);
|
|
||||||
final int length = values.count();
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
GeoPoint point = values.valueAt(i);
|
|
||||||
if (pointInPolygon(points, point.lat(), point.lon())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean pointInPolygon(GeoPoint[] points, double lat, double lon) {
|
|
||||||
boolean inPoly = false;
|
|
||||||
|
|
||||||
for (int i = 1; i < points.length; i++) {
|
|
||||||
if (points[i].lon() < lon && points[i-1].lon() >= lon
|
|
||||||
|| points[i-1].lon() < lon && points[i].lon() >= lon) {
|
|
||||||
if (points[i].lat() + (lon - points[i].lon()) /
|
|
||||||
(points[i-1].lon() - points[i].lon()) * (points[i-1].lat() - points[i].lat()) < lat) {
|
|
||||||
inPoly = !inPoly;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return inPoly;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch 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.elasticsearch.index.search.geo;
|
||||||
|
|
||||||
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
|
import org.apache.lucene.search.IndexSearcher;
|
||||||
|
import org.apache.lucene.search.Query;
|
||||||
|
import org.apache.lucene.search.RandomAccessWeight;
|
||||||
|
import org.apache.lucene.search.Weight;
|
||||||
|
import org.apache.lucene.util.Bits;
|
||||||
|
import org.elasticsearch.common.geo.GeoPoint;
|
||||||
|
import org.elasticsearch.index.fielddata.IndexGeoPointFieldData;
|
||||||
|
import org.elasticsearch.index.fielddata.MultiGeoPointValues;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GeoPolygonQuery extends Query {
|
||||||
|
|
||||||
|
private final GeoPoint[] points;
|
||||||
|
|
||||||
|
private final IndexGeoPointFieldData indexFieldData;
|
||||||
|
|
||||||
|
public GeoPolygonQuery(IndexGeoPointFieldData indexFieldData, GeoPoint...points) {
|
||||||
|
this.points = points;
|
||||||
|
this.indexFieldData = indexFieldData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GeoPoint[] points() {
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String fieldName() {
|
||||||
|
return indexFieldData.getFieldNames().indexName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
|
||||||
|
return new RandomAccessWeight(this) {
|
||||||
|
@Override
|
||||||
|
protected Bits getMatchingDocs(LeafReaderContext context) throws IOException {
|
||||||
|
final int maxDoc = context.reader().maxDoc();
|
||||||
|
final MultiGeoPointValues values = indexFieldData.load(context).getGeoPointValues();
|
||||||
|
return new Bits() {
|
||||||
|
|
||||||
|
private boolean pointInPolygon(GeoPoint[] points, double lat, double lon) {
|
||||||
|
boolean inPoly = false;
|
||||||
|
|
||||||
|
for (int i = 1; i < points.length; i++) {
|
||||||
|
if (points[i].lon() < lon && points[i-1].lon() >= lon
|
||||||
|
|| points[i-1].lon() < lon && points[i].lon() >= lon) {
|
||||||
|
if (points[i].lat() + (lon - points[i].lon()) /
|
||||||
|
(points[i-1].lon() - points[i].lon()) * (points[i-1].lat() - points[i].lat()) < lat) {
|
||||||
|
inPoly = !inPoly;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return inPoly;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean get(int doc) {
|
||||||
|
values.setDocument(doc);
|
||||||
|
final int length = values.count();
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
GeoPoint point = values.valueAt(i);
|
||||||
|
if (pointInPolygon(points, point.lat(), point.lon())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int length() {
|
||||||
|
return maxDoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(String field) {
|
||||||
|
StringBuilder sb = new StringBuilder("GeoPolygonFilter(");
|
||||||
|
sb.append(indexFieldData.getFieldNames().indexName());
|
||||||
|
sb.append(", ").append(Arrays.toString(points)).append(')');
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (super.equals(obj) == false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
GeoPolygonQuery that = (GeoPolygonQuery) obj;
|
||||||
|
return indexFieldData.getFieldNames().indexName().equals(that.indexFieldData.getFieldNames().indexName())
|
||||||
|
&& Arrays.equals(points, that.points);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int h = super.hashCode();
|
||||||
|
h = 31 * h + indexFieldData.getFieldNames().indexName().hashCode();
|
||||||
|
h = 31 * h + Arrays.hashCode(points);
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,29 +19,29 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.search.geo;
|
package org.elasticsearch.index.search.geo;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
import org.apache.lucene.search.DocIdSet;
|
import org.apache.lucene.search.IndexSearcher;
|
||||||
import org.apache.lucene.search.DocValuesDocIdSet;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.Filter;
|
import org.apache.lucene.search.RandomAccessWeight;
|
||||||
|
import org.apache.lucene.search.Weight;
|
||||||
import org.apache.lucene.util.Bits;
|
import org.apache.lucene.util.Bits;
|
||||||
import org.elasticsearch.common.Nullable;
|
|
||||||
import org.elasticsearch.common.geo.GeoPoint;
|
import org.elasticsearch.common.geo.GeoPoint;
|
||||||
import org.elasticsearch.index.fielddata.IndexGeoPointFieldData;
|
import org.elasticsearch.index.fielddata.IndexGeoPointFieldData;
|
||||||
import org.elasticsearch.index.fielddata.MultiGeoPointValues;
|
import org.elasticsearch.index.fielddata.MultiGeoPointValues;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class InMemoryGeoBoundingBoxFilter extends Filter {
|
public class InMemoryGeoBoundingBoxQuery extends Query {
|
||||||
|
|
||||||
private final GeoPoint topLeft;
|
private final GeoPoint topLeft;
|
||||||
private final GeoPoint bottomRight;
|
private final GeoPoint bottomRight;
|
||||||
|
|
||||||
private final IndexGeoPointFieldData indexFieldData;
|
private final IndexGeoPointFieldData indexFieldData;
|
||||||
|
|
||||||
public InMemoryGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, IndexGeoPointFieldData indexFieldData) {
|
public InMemoryGeoBoundingBoxQuery(GeoPoint topLeft, GeoPoint bottomRight, IndexGeoPointFieldData indexFieldData) {
|
||||||
this.topLeft = topLeft;
|
this.topLeft = topLeft;
|
||||||
this.bottomRight = bottomRight;
|
this.bottomRight = bottomRight;
|
||||||
this.indexFieldData = indexFieldData;
|
this.indexFieldData = indexFieldData;
|
||||||
|
@ -60,16 +60,21 @@ public class InMemoryGeoBoundingBoxFilter extends Filter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptedDocs) throws IOException {
|
public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
|
||||||
|
return new RandomAccessWeight(this) {
|
||||||
|
@Override
|
||||||
|
protected Bits getMatchingDocs(LeafReaderContext context) throws IOException {
|
||||||
|
final int maxDoc = context.reader().maxDoc();
|
||||||
final MultiGeoPointValues values = indexFieldData.load(context).getGeoPointValues();
|
final MultiGeoPointValues values = indexFieldData.load(context).getGeoPointValues();
|
||||||
|
// checks to see if bounding box crosses 180 degrees
|
||||||
//checks to see if bounding box crosses 180 degrees
|
|
||||||
if (topLeft.lon() > bottomRight.lon()) {
|
if (topLeft.lon() > bottomRight.lon()) {
|
||||||
return new Meridian180GeoBoundingBoxDocSet(context.reader().maxDoc(), acceptedDocs, values, topLeft, bottomRight);
|
return new Meridian180GeoBoundingBoxBits(maxDoc, values, topLeft, bottomRight);
|
||||||
} else {
|
} else {
|
||||||
return new GeoBoundingBoxDocSet(context.reader().maxDoc(), acceptedDocs, values, topLeft, bottomRight);
|
return new GeoBoundingBoxBits(maxDoc, values, topLeft, bottomRight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(String field) {
|
public String toString(String field) {
|
||||||
|
@ -81,7 +86,7 @@ public class InMemoryGeoBoundingBoxFilter extends Filter {
|
||||||
if (super.equals(obj) == false) {
|
if (super.equals(obj) == false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
InMemoryGeoBoundingBoxFilter other = (InMemoryGeoBoundingBoxFilter) obj;
|
InMemoryGeoBoundingBoxQuery other = (InMemoryGeoBoundingBoxQuery) obj;
|
||||||
return fieldName().equalsIgnoreCase(other.fieldName())
|
return fieldName().equalsIgnoreCase(other.fieldName())
|
||||||
&& topLeft.equals(other.topLeft)
|
&& topLeft.equals(other.topLeft)
|
||||||
&& bottomRight.equals(other.bottomRight);
|
&& bottomRight.equals(other.bottomRight);
|
||||||
|
@ -96,20 +101,21 @@ public class InMemoryGeoBoundingBoxFilter extends Filter {
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Meridian180GeoBoundingBoxDocSet extends DocValuesDocIdSet {
|
private static class Meridian180GeoBoundingBoxBits implements Bits {
|
||||||
|
private final int maxDoc;
|
||||||
private final MultiGeoPointValues values;
|
private final MultiGeoPointValues values;
|
||||||
private final GeoPoint topLeft;
|
private final GeoPoint topLeft;
|
||||||
private final GeoPoint bottomRight;
|
private final GeoPoint bottomRight;
|
||||||
|
|
||||||
public Meridian180GeoBoundingBoxDocSet(int maxDoc, @Nullable Bits acceptDocs, MultiGeoPointValues values, GeoPoint topLeft, GeoPoint bottomRight) {
|
public Meridian180GeoBoundingBoxBits(int maxDoc, MultiGeoPointValues values, GeoPoint topLeft, GeoPoint bottomRight) {
|
||||||
super(maxDoc, acceptDocs);
|
this.maxDoc = maxDoc;
|
||||||
this.values = values;
|
this.values = values;
|
||||||
this.topLeft = topLeft;
|
this.topLeft = topLeft;
|
||||||
this.bottomRight = bottomRight;
|
this.bottomRight = bottomRight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean matchDoc(int doc) {
|
public boolean get(int doc) {
|
||||||
values.setDocument(doc);
|
values.setDocument(doc);
|
||||||
final int length = values.count();
|
final int length = values.count();
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
|
@ -121,22 +127,28 @@ public class InMemoryGeoBoundingBoxFilter extends Filter {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int length() {
|
||||||
|
return maxDoc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class GeoBoundingBoxDocSet extends DocValuesDocIdSet {
|
private static class GeoBoundingBoxBits implements Bits {
|
||||||
|
private final int maxDoc;
|
||||||
private final MultiGeoPointValues values;
|
private final MultiGeoPointValues values;
|
||||||
private final GeoPoint topLeft;
|
private final GeoPoint topLeft;
|
||||||
private final GeoPoint bottomRight;
|
private final GeoPoint bottomRight;
|
||||||
|
|
||||||
public GeoBoundingBoxDocSet(int maxDoc, @Nullable Bits acceptDocs, MultiGeoPointValues values, GeoPoint topLeft, GeoPoint bottomRight) {
|
public GeoBoundingBoxBits(int maxDoc, MultiGeoPointValues values, GeoPoint topLeft, GeoPoint bottomRight) {
|
||||||
super(maxDoc, acceptDocs);
|
this.maxDoc = maxDoc;
|
||||||
this.values = values;
|
this.values = values;
|
||||||
this.topLeft = topLeft;
|
this.topLeft = topLeft;
|
||||||
this.bottomRight = bottomRight;
|
this.bottomRight = bottomRight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean matchDoc(int doc) {
|
public boolean get(int doc) {
|
||||||
values.setDocument(doc);
|
values.setDocument(doc);
|
||||||
final int length = values.count();
|
final int length = values.count();
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
|
@ -148,5 +160,10 @@ public class InMemoryGeoBoundingBoxFilter extends Filter {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int length() {
|
||||||
|
return maxDoc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,16 +21,16 @@ package org.elasticsearch.index.search.geo;
|
||||||
|
|
||||||
import org.apache.lucene.search.BooleanClause.Occur;
|
import org.apache.lucene.search.BooleanClause.Occur;
|
||||||
import org.apache.lucene.search.BooleanQuery;
|
import org.apache.lucene.search.BooleanQuery;
|
||||||
import org.apache.lucene.search.Filter;
|
import org.apache.lucene.search.ConstantScoreQuery;
|
||||||
import org.apache.lucene.search.QueryWrapperFilter;
|
import org.apache.lucene.search.Query;
|
||||||
import org.elasticsearch.common.geo.GeoPoint;
|
import org.elasticsearch.common.geo.GeoPoint;
|
||||||
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public class IndexedGeoBoundingBoxFilter {
|
public class IndexedGeoBoundingBoxQuery {
|
||||||
|
|
||||||
public static Filter create(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) {
|
public static Query create(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) {
|
||||||
if (!fieldMapper.isEnableLatLon()) {
|
if (!fieldMapper.isEnableLatLon()) {
|
||||||
throw new IllegalArgumentException("lat/lon is not enabled (indexed) for field [" + fieldMapper.name() + "], can't use indexed filter on it");
|
throw new IllegalArgumentException("lat/lon is not enabled (indexed) for field [" + fieldMapper.name() + "], can't use indexed filter on it");
|
||||||
}
|
}
|
||||||
|
@ -42,19 +42,19 @@ public class IndexedGeoBoundingBoxFilter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Filter westGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) {
|
private static Query westGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) {
|
||||||
BooleanQuery filter = new BooleanQuery();
|
BooleanQuery filter = new BooleanQuery();
|
||||||
filter.setMinimumNumberShouldMatch(1);
|
filter.setMinimumNumberShouldMatch(1);
|
||||||
filter.add(fieldMapper.lonMapper().rangeFilter(null, bottomRight.lon(), true, true), Occur.SHOULD);
|
filter.add(fieldMapper.lonMapper().rangeFilter(null, bottomRight.lon(), true, true), Occur.SHOULD);
|
||||||
filter.add(fieldMapper.lonMapper().rangeFilter(topLeft.lon(), null, true, true), Occur.SHOULD);
|
filter.add(fieldMapper.lonMapper().rangeFilter(topLeft.lon(), null, true, true), Occur.SHOULD);
|
||||||
filter.add(fieldMapper.latMapper().rangeFilter(bottomRight.lat(), topLeft.lat(), true, true), Occur.MUST);
|
filter.add(fieldMapper.latMapper().rangeFilter(bottomRight.lat(), topLeft.lat(), true, true), Occur.MUST);
|
||||||
return new QueryWrapperFilter(filter);
|
return new ConstantScoreQuery(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Filter eastGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) {
|
private static Query eastGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) {
|
||||||
BooleanQuery filter = new BooleanQuery();
|
BooleanQuery filter = new BooleanQuery();
|
||||||
filter.add(fieldMapper.lonMapper().rangeFilter(topLeft.lon(), bottomRight.lon(), true, true), Occur.MUST);
|
filter.add(fieldMapper.lonMapper().rangeFilter(topLeft.lon(), bottomRight.lon(), true, true), Occur.MUST);
|
||||||
filter.add(fieldMapper.latMapper().rangeFilter(bottomRight.lat(), topLeft.lat(), true, true), Occur.MUST);
|
filter.add(fieldMapper.latMapper().rangeFilter(bottomRight.lat(), topLeft.lat(), true, true), Occur.MUST);
|
||||||
return new QueryWrapperFilter(filter);
|
return new ConstantScoreQuery(filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,96 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to Elasticsearch under one or more contributor
|
|
||||||
* license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright
|
|
||||||
* ownership. Elasticsearch 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.elasticsearch.common.lucene.search;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.apache.lucene.search.DocIdSet;
|
|
||||||
import org.apache.lucene.search.DocIdSetIterator;
|
|
||||||
import org.apache.lucene.search.DocValuesDocIdSet;
|
|
||||||
import org.apache.lucene.util.BitDocIdSet;
|
|
||||||
import org.apache.lucene.util.Bits;
|
|
||||||
import org.apache.lucene.util.FixedBitSet;
|
|
||||||
import org.elasticsearch.common.lucene.docset.AndDocIdSet;
|
|
||||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
|
||||||
|
|
||||||
public class AndDocIdSetTests extends ElasticsearchTestCase {
|
|
||||||
|
|
||||||
private static FixedBitSet randomBitSet(int numDocs) {
|
|
||||||
FixedBitSet b = new FixedBitSet(numDocs);
|
|
||||||
for (int i = 0; i < numDocs; ++i) {
|
|
||||||
if (random().nextBoolean()) {
|
|
||||||
b.set(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDuel() throws IOException {
|
|
||||||
for (int iter = 0; iter < 1000; ++iter) {
|
|
||||||
final int numSets = 1 + random().nextInt(5);
|
|
||||||
final int numDocs = 1 + random().nextInt(1000);
|
|
||||||
FixedBitSet anded = new FixedBitSet(numDocs);
|
|
||||||
anded.set(0, numDocs);
|
|
||||||
final DocIdSet[] sets = new DocIdSet[numSets];
|
|
||||||
for (int i = 0; i < numSets; ++i) {
|
|
||||||
final FixedBitSet randomSet = randomBitSet(numDocs);
|
|
||||||
|
|
||||||
anded.and(randomSet);
|
|
||||||
|
|
||||||
if (random().nextBoolean()) {
|
|
||||||
// will be considered 'fast' by AndDocIdSet
|
|
||||||
sets[i] = new BitDocIdSet(randomSet);
|
|
||||||
} else {
|
|
||||||
// will be considered 'slow' by AndDocIdSet
|
|
||||||
sets[i] = new DocValuesDocIdSet(numDocs, null) {
|
|
||||||
@Override
|
|
||||||
protected boolean matchDoc(int doc) {
|
|
||||||
return randomSet.get(doc);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AndDocIdSet andSet = new AndDocIdSet(sets);
|
|
||||||
Bits andBits = andSet.bits();
|
|
||||||
if (andBits != null) {
|
|
||||||
for (int i = 0; i < numDocs; ++i) {
|
|
||||||
assertEquals(anded.get(i), andBits.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DocIdSetIterator andIt = andSet.iterator();
|
|
||||||
if (andIt == null) {
|
|
||||||
assertEquals(0, anded.cardinality());
|
|
||||||
} else {
|
|
||||||
int previous = -1;
|
|
||||||
for (int doc = andIt.nextDoc(); doc != DocIdSetIterator.NO_MORE_DOCS; doc = andIt.nextDoc()) {
|
|
||||||
for (int j = previous + 1; j < doc; ++j) {
|
|
||||||
assertFalse(anded.get(j));
|
|
||||||
}
|
|
||||||
assertTrue(anded.get(doc));
|
|
||||||
previous = doc;
|
|
||||||
}
|
|
||||||
for (int j = previous + 1; j < numDocs; ++j) {
|
|
||||||
assertFalse(anded.get(j));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -90,9 +90,9 @@ import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.mapper.ParsedDocument;
|
import org.elasticsearch.index.mapper.ParsedDocument;
|
||||||
import org.elasticsearch.index.mapper.core.NumberFieldMapper;
|
import org.elasticsearch.index.mapper.core.NumberFieldMapper;
|
||||||
import org.elasticsearch.index.search.child.ParentConstantScoreQuery;
|
import org.elasticsearch.index.search.child.ParentConstantScoreQuery;
|
||||||
import org.elasticsearch.index.search.geo.GeoDistanceFilter;
|
import org.elasticsearch.index.search.geo.GeoDistanceRangeQuery;
|
||||||
import org.elasticsearch.index.search.geo.GeoPolygonFilter;
|
import org.elasticsearch.index.search.geo.GeoPolygonQuery;
|
||||||
import org.elasticsearch.index.search.geo.InMemoryGeoBoundingBoxFilter;
|
import org.elasticsearch.index.search.geo.InMemoryGeoBoundingBoxQuery;
|
||||||
import org.elasticsearch.index.search.morelikethis.MoreLikeThisFetchService;
|
import org.elasticsearch.index.search.morelikethis.MoreLikeThisFetchService;
|
||||||
import org.elasticsearch.search.internal.SearchContext;
|
import org.elasticsearch.search.internal.SearchContext;
|
||||||
import org.elasticsearch.test.ElasticsearchSingleNodeTest;
|
import org.elasticsearch.test.ElasticsearchSingleNodeTest;
|
||||||
|
@ -134,7 +134,6 @@ import static org.elasticsearch.index.query.QueryBuilders.spanTermQuery;
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.spanWithinQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.spanWithinQuery;
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
|
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.wildcardQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.wildcardQuery;
|
||||||
import static org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders.factorFunction;
|
import static org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders.factorFunction;
|
||||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBooleanSubQuery;
|
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBooleanSubQuery;
|
||||||
|
@ -1803,186 +1802,199 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeoDistanceFilterNamed() throws IOException {
|
public void testGeoDistanceRangeQueryNamed() throws IOException {
|
||||||
IndexQueryParserService queryParser = queryParser();
|
IndexQueryParserService queryParser = queryParser();
|
||||||
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance-named.json");
|
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance-named.json");
|
||||||
ParsedQuery parsedQuery = queryParser.parse(query);
|
ParsedQuery parsedQuery = queryParser.parse(query);
|
||||||
assertThat(parsedQuery.namedFilters().containsKey("test"), equalTo(true));
|
assertThat(parsedQuery.namedFilters().containsKey("test"), equalTo(true));
|
||||||
assertThat(parsedQuery.query(), instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery.query(), instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery.query();
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery.query();
|
||||||
GeoDistanceFilter filter = (GeoDistanceFilter) constantScoreQuery.getQuery();
|
GeoDistanceRangeQuery filter = (GeoDistanceRangeQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.lat(), closeTo(40, 0.00001));
|
assertThat(filter.lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
||||||
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
assertThat(filter.minInclusiveDistance(), equalTo(Double.NEGATIVE_INFINITY));
|
||||||
|
assertThat(filter.maxInclusiveDistance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeoDistanceFilter1() throws IOException {
|
public void testGeoDistanceRangeQuery1() throws IOException {
|
||||||
IndexQueryParserService queryParser = queryParser();
|
IndexQueryParserService queryParser = queryParser();
|
||||||
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance1.json");
|
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance1.json");
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
GeoDistanceFilter filter = (GeoDistanceFilter) constantScoreQuery.getQuery();
|
GeoDistanceRangeQuery filter = (GeoDistanceRangeQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.lat(), closeTo(40, 0.00001));
|
assertThat(filter.lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
||||||
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
assertThat(filter.minInclusiveDistance(), equalTo(Double.NEGATIVE_INFINITY));
|
||||||
|
assertThat(filter.maxInclusiveDistance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeoDistanceFilter2() throws IOException {
|
public void testGeoDistanceRangeQuery2() throws IOException {
|
||||||
IndexQueryParserService queryParser = queryParser();
|
IndexQueryParserService queryParser = queryParser();
|
||||||
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance2.json");
|
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance2.json");
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
GeoDistanceFilter filter = (GeoDistanceFilter) constantScoreQuery.getQuery();
|
GeoDistanceRangeQuery filter = (GeoDistanceRangeQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.lat(), closeTo(40, 0.00001));
|
assertThat(filter.lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
||||||
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
assertThat(filter.minInclusiveDistance(), equalTo(Double.NEGATIVE_INFINITY));
|
||||||
|
assertThat(filter.maxInclusiveDistance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeoDistanceFilter3() throws IOException {
|
public void testGeoDistanceRangeQuery3() throws IOException {
|
||||||
IndexQueryParserService queryParser = queryParser();
|
IndexQueryParserService queryParser = queryParser();
|
||||||
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance3.json");
|
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance3.json");
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
GeoDistanceFilter filter = (GeoDistanceFilter) constantScoreQuery.getQuery();
|
GeoDistanceRangeQuery filter = (GeoDistanceRangeQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.lat(), closeTo(40, 0.00001));
|
assertThat(filter.lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
||||||
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
assertThat(filter.minInclusiveDistance(), equalTo(Double.NEGATIVE_INFINITY));
|
||||||
|
assertThat(filter.maxInclusiveDistance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeoDistanceFilter4() throws IOException {
|
public void testGeoDistanceRangeQuery4() throws IOException {
|
||||||
IndexQueryParserService queryParser = queryParser();
|
IndexQueryParserService queryParser = queryParser();
|
||||||
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance4.json");
|
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance4.json");
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
GeoDistanceFilter filter = (GeoDistanceFilter) constantScoreQuery.getQuery();
|
GeoDistanceRangeQuery filter = (GeoDistanceRangeQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.lat(), closeTo(40, 0.00001));
|
assertThat(filter.lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
||||||
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
assertThat(filter.minInclusiveDistance(), equalTo(Double.NEGATIVE_INFINITY));
|
||||||
|
assertThat(filter.maxInclusiveDistance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeoDistanceFilter5() throws IOException {
|
public void testGeoDistanceRangeQuery5() throws IOException {
|
||||||
IndexQueryParserService queryParser = queryParser();
|
IndexQueryParserService queryParser = queryParser();
|
||||||
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance5.json");
|
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance5.json");
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
GeoDistanceFilter filter = (GeoDistanceFilter) constantScoreQuery.getQuery();
|
GeoDistanceRangeQuery filter = (GeoDistanceRangeQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.lat(), closeTo(40, 0.00001));
|
assertThat(filter.lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
||||||
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
assertThat(filter.minInclusiveDistance(), equalTo(Double.NEGATIVE_INFINITY));
|
||||||
|
assertThat(filter.maxInclusiveDistance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeoDistanceFilter6() throws IOException {
|
public void testGeoDistanceRangeQuery6() throws IOException {
|
||||||
IndexQueryParserService queryParser = queryParser();
|
IndexQueryParserService queryParser = queryParser();
|
||||||
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance6.json");
|
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance6.json");
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
GeoDistanceFilter filter = (GeoDistanceFilter) constantScoreQuery.getQuery();
|
GeoDistanceRangeQuery filter = (GeoDistanceRangeQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.lat(), closeTo(40, 0.00001));
|
assertThat(filter.lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
||||||
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
assertThat(filter.minInclusiveDistance(), equalTo(Double.NEGATIVE_INFINITY));
|
||||||
|
assertThat(filter.maxInclusiveDistance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeoDistanceFilter7() throws IOException {
|
public void testGeoDistanceRangeQuery7() throws IOException {
|
||||||
IndexQueryParserService queryParser = queryParser();
|
IndexQueryParserService queryParser = queryParser();
|
||||||
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance7.json");
|
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance7.json");
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
GeoDistanceFilter filter = (GeoDistanceFilter) constantScoreQuery.getQuery();
|
GeoDistanceRangeQuery filter = (GeoDistanceRangeQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.lat(), closeTo(40, 0.00001));
|
assertThat(filter.lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
||||||
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(0.012, DistanceUnit.MILES), 0.00001));
|
assertThat(filter.minInclusiveDistance(), equalTo(Double.NEGATIVE_INFINITY));
|
||||||
|
assertThat(filter.maxInclusiveDistance(), closeTo(DistanceUnit.DEFAULT.convert(0.012, DistanceUnit.MILES), 0.00001));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeoDistanceFilter8() throws IOException {
|
public void testGeoDistanceRangeQuery8() throws IOException {
|
||||||
IndexQueryParserService queryParser = queryParser();
|
IndexQueryParserService queryParser = queryParser();
|
||||||
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance8.json");
|
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance8.json");
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
GeoDistanceFilter filter = (GeoDistanceFilter) constantScoreQuery.getQuery();
|
GeoDistanceRangeQuery filter = (GeoDistanceRangeQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.lat(), closeTo(40, 0.00001));
|
assertThat(filter.lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
||||||
assertThat(filter.distance(), closeTo(DistanceUnit.KILOMETERS.convert(12, DistanceUnit.MILES), 0.00001));
|
assertThat(filter.minInclusiveDistance(), equalTo(Double.NEGATIVE_INFINITY));
|
||||||
|
assertThat(filter.maxInclusiveDistance(), closeTo(DistanceUnit.KILOMETERS.convert(12, DistanceUnit.MILES), 0.00001));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeoDistanceFilter9() throws IOException {
|
public void testGeoDistanceRangeQuery9() throws IOException {
|
||||||
IndexQueryParserService queryParser = queryParser();
|
IndexQueryParserService queryParser = queryParser();
|
||||||
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance9.json");
|
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance9.json");
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
GeoDistanceFilter filter = (GeoDistanceFilter) constantScoreQuery.getQuery();
|
GeoDistanceRangeQuery filter = (GeoDistanceRangeQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.lat(), closeTo(40, 0.00001));
|
assertThat(filter.lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
||||||
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
assertThat(filter.minInclusiveDistance(), equalTo(Double.NEGATIVE_INFINITY));
|
||||||
|
assertThat(filter.maxInclusiveDistance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeoDistanceFilter10() throws IOException {
|
public void testGeoDistanceRangeQuery10() throws IOException {
|
||||||
IndexQueryParserService queryParser = queryParser();
|
IndexQueryParserService queryParser = queryParser();
|
||||||
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance10.json");
|
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance10.json");
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
GeoDistanceFilter filter = (GeoDistanceFilter) constantScoreQuery.getQuery();
|
GeoDistanceRangeQuery filter = (GeoDistanceRangeQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.lat(), closeTo(40, 0.00001));
|
assertThat(filter.lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
||||||
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
assertThat(filter.minInclusiveDistance(), equalTo(Double.NEGATIVE_INFINITY));
|
||||||
|
assertThat(filter.maxInclusiveDistance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeoDistanceFilter11() throws IOException {
|
public void testGeoDistanceRangeQuery11() throws IOException {
|
||||||
IndexQueryParserService queryParser = queryParser();
|
IndexQueryParserService queryParser = queryParser();
|
||||||
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance11.json");
|
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance11.json");
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
GeoDistanceFilter filter = (GeoDistanceFilter) constantScoreQuery.getQuery();
|
GeoDistanceRangeQuery filter = (GeoDistanceRangeQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.lat(), closeTo(40, 0.00001));
|
assertThat(filter.lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
||||||
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
assertThat(filter.minInclusiveDistance(), equalTo(Double.NEGATIVE_INFINITY));
|
||||||
|
assertThat(filter.maxInclusiveDistance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeoDistanceFilter12() throws IOException {
|
public void testGeoDistanceRangeQuery12() throws IOException {
|
||||||
IndexQueryParserService queryParser = queryParser();
|
IndexQueryParserService queryParser = queryParser();
|
||||||
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance12.json");
|
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_distance12.json");
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
GeoDistanceFilter filter = (GeoDistanceFilter) constantScoreQuery.getQuery();
|
GeoDistanceRangeQuery filter = (GeoDistanceRangeQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.lat(), closeTo(40, 0.00001));
|
assertThat(filter.lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
assertThat(filter.lon(), closeTo(-70, 0.00001));
|
||||||
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
assertThat(filter.minInclusiveDistance(), equalTo(Double.NEGATIVE_INFINITY));
|
||||||
|
assertThat(filter.maxInclusiveDistance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1993,7 +2005,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
|
||||||
assertThat(parsedQuery.query(), instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery.query(), instanceOf(ConstantScoreQuery.class));
|
||||||
assertThat(parsedQuery.namedFilters().containsKey("test"), equalTo(true));
|
assertThat(parsedQuery.namedFilters().containsKey("test"), equalTo(true));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery.query();
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery.query();
|
||||||
InMemoryGeoBoundingBoxFilter filter = (InMemoryGeoBoundingBoxFilter) constantScoreQuery.getQuery();
|
InMemoryGeoBoundingBoxQuery filter = (InMemoryGeoBoundingBoxQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.topLeft().lat(), closeTo(40, 0.00001));
|
assertThat(filter.topLeft().lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001));
|
assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001));
|
||||||
|
@ -2009,7 +2021,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
InMemoryGeoBoundingBoxFilter filter = (InMemoryGeoBoundingBoxFilter) constantScoreQuery.getQuery();
|
InMemoryGeoBoundingBoxQuery filter = (InMemoryGeoBoundingBoxQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.topLeft().lat(), closeTo(40, 0.00001));
|
assertThat(filter.topLeft().lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001));
|
assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001));
|
||||||
|
@ -2024,7 +2036,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
InMemoryGeoBoundingBoxFilter filter = (InMemoryGeoBoundingBoxFilter) constantScoreQuery.getQuery();
|
InMemoryGeoBoundingBoxQuery filter = (InMemoryGeoBoundingBoxQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.topLeft().lat(), closeTo(40, 0.00001));
|
assertThat(filter.topLeft().lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001));
|
assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001));
|
||||||
|
@ -2039,7 +2051,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
InMemoryGeoBoundingBoxFilter filter = (InMemoryGeoBoundingBoxFilter) constantScoreQuery.getQuery();
|
InMemoryGeoBoundingBoxQuery filter = (InMemoryGeoBoundingBoxQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.topLeft().lat(), closeTo(40, 0.00001));
|
assertThat(filter.topLeft().lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001));
|
assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001));
|
||||||
|
@ -2054,7 +2066,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
InMemoryGeoBoundingBoxFilter filter = (InMemoryGeoBoundingBoxFilter) constantScoreQuery.getQuery();
|
InMemoryGeoBoundingBoxQuery filter = (InMemoryGeoBoundingBoxQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.topLeft().lat(), closeTo(40, 0.00001));
|
assertThat(filter.topLeft().lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001));
|
assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001));
|
||||||
|
@ -2069,7 +2081,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
InMemoryGeoBoundingBoxFilter filter = (InMemoryGeoBoundingBoxFilter) constantScoreQuery.getQuery();
|
InMemoryGeoBoundingBoxQuery filter = (InMemoryGeoBoundingBoxQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.topLeft().lat(), closeTo(40, 0.00001));
|
assertThat(filter.topLeft().lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001));
|
assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001));
|
||||||
|
@ -2084,7 +2096,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
InMemoryGeoBoundingBoxFilter filter = (InMemoryGeoBoundingBoxFilter) constantScoreQuery.getQuery();
|
InMemoryGeoBoundingBoxQuery filter = (InMemoryGeoBoundingBoxQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.topLeft().lat(), closeTo(40, 0.00001));
|
assertThat(filter.topLeft().lat(), closeTo(40, 0.00001));
|
||||||
assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001));
|
assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001));
|
||||||
|
@ -2101,7 +2113,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
|
||||||
assertThat(parsedQuery.namedFilters().containsKey("test"), equalTo(true));
|
assertThat(parsedQuery.namedFilters().containsKey("test"), equalTo(true));
|
||||||
assertThat(parsedQuery.query(), instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery.query(), instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery.query();
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery.query();
|
||||||
GeoPolygonFilter filter = (GeoPolygonFilter) constantScoreQuery.getQuery();
|
GeoPolygonQuery filter = (GeoPolygonQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.points().length, equalTo(4));
|
assertThat(filter.points().length, equalTo(4));
|
||||||
assertThat(filter.points()[0].lat(), closeTo(40, 0.00001));
|
assertThat(filter.points()[0].lat(), closeTo(40, 0.00001));
|
||||||
|
@ -2142,7 +2154,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
GeoPolygonFilter filter = (GeoPolygonFilter) constantScoreQuery.getQuery();
|
GeoPolygonQuery filter = (GeoPolygonQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.points().length, equalTo(4));
|
assertThat(filter.points().length, equalTo(4));
|
||||||
assertThat(filter.points()[0].lat(), closeTo(40, 0.00001));
|
assertThat(filter.points()[0].lat(), closeTo(40, 0.00001));
|
||||||
|
@ -2160,7 +2172,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
GeoPolygonFilter filter = (GeoPolygonFilter) constantScoreQuery.getQuery();
|
GeoPolygonQuery filter = (GeoPolygonQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.points().length, equalTo(4));
|
assertThat(filter.points().length, equalTo(4));
|
||||||
assertThat(filter.points()[0].lat(), closeTo(40, 0.00001));
|
assertThat(filter.points()[0].lat(), closeTo(40, 0.00001));
|
||||||
|
@ -2178,7 +2190,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
GeoPolygonFilter filter = (GeoPolygonFilter) constantScoreQuery.getQuery();
|
GeoPolygonQuery filter = (GeoPolygonQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.points().length, equalTo(4));
|
assertThat(filter.points().length, equalTo(4));
|
||||||
assertThat(filter.points()[0].lat(), closeTo(40, 0.00001));
|
assertThat(filter.points()[0].lat(), closeTo(40, 0.00001));
|
||||||
|
@ -2196,7 +2208,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
|
||||||
Query parsedQuery = queryParser.parse(query).query();
|
Query parsedQuery = queryParser.parse(query).query();
|
||||||
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) parsedQuery;
|
||||||
GeoPolygonFilter filter = (GeoPolygonFilter) constantScoreQuery.getQuery();
|
GeoPolygonQuery filter = (GeoPolygonQuery) constantScoreQuery.getQuery();
|
||||||
assertThat(filter.fieldName(), equalTo("location"));
|
assertThat(filter.fieldName(), equalTo("location"));
|
||||||
assertThat(filter.points().length, equalTo(4));
|
assertThat(filter.points().length, equalTo(4));
|
||||||
assertThat(filter.points()[0].lat(), closeTo(40, 0.00001));
|
assertThat(filter.points()[0].lat(), closeTo(40, 0.00001));
|
||||||
|
|
Loading…
Reference in New Issue