From 2b639ae1b5e62ead1f21e7363b958d81d0df7999 Mon Sep 17 00:00:00 2001 From: Adrien Grand Date: Mon, 3 Nov 2014 10:31:29 +0100 Subject: [PATCH] Geo: Fix IndexedGeoBoundingBoxFilter to not modify the bits of other filters. Close #8325 --- .../geo/IndexedGeoBoundingBoxFilter.java | 135 ++---------------- 1 file changed, 15 insertions(+), 120 deletions(-) diff --git a/src/main/java/org/elasticsearch/index/search/geo/IndexedGeoBoundingBoxFilter.java b/src/main/java/org/elasticsearch/index/search/geo/IndexedGeoBoundingBoxFilter.java index cac948f92f3..2355245e958 100644 --- a/src/main/java/org/elasticsearch/index/search/geo/IndexedGeoBoundingBoxFilter.java +++ b/src/main/java/org/elasticsearch/index/search/geo/IndexedGeoBoundingBoxFilter.java @@ -19,18 +19,13 @@ package org.elasticsearch.index.search.geo; -import org.apache.lucene.index.AtomicReaderContext; -import org.apache.lucene.search.DocIdSet; +import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.Filter; -import org.apache.lucene.util.Bits; -import org.apache.lucene.util.FixedBitSet; import org.elasticsearch.ElasticsearchIllegalArgumentException; import org.elasticsearch.common.geo.GeoPoint; -import org.elasticsearch.common.lucene.docset.DocIdSets; +import org.elasticsearch.common.lucene.search.XBooleanFilter; import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper; -import java.io.IOException; - /** */ public class IndexedGeoBoundingBoxFilter { @@ -41,124 +36,24 @@ public class IndexedGeoBoundingBoxFilter { } //checks to see if bounding box crosses 180 degrees if (topLeft.lon() > bottomRight.lon()) { - return new WestGeoBoundingBoxFilter(topLeft, bottomRight, fieldMapper); + return westGeoBoundingBoxFilter(topLeft, bottomRight, fieldMapper); } else { - return new EastGeoBoundingBoxFilter(topLeft, bottomRight, fieldMapper); + return eastGeoBoundingBoxFilter(topLeft, bottomRight, fieldMapper); } } - static class WestGeoBoundingBoxFilter extends Filter { - - final Filter lonFilter1; - final Filter lonFilter2; - final Filter latFilter; - - public WestGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) { - lonFilter1 = fieldMapper.lonMapper().rangeFilter(null, bottomRight.lon(), true, true); - lonFilter2 = fieldMapper.lonMapper().rangeFilter(topLeft.lon(), null, true, true); - latFilter = fieldMapper.latMapper().rangeFilter(bottomRight.lat(), topLeft.lat(), true, true); - } - - @Override - public DocIdSet getDocIdSet(AtomicReaderContext context, Bits acceptedDocs) throws IOException { - FixedBitSet main; - DocIdSet set = lonFilter1.getDocIdSet(context, acceptedDocs); - if (DocIdSets.isEmpty(set)) { - main = null; - } else { - main = (FixedBitSet) set; - } - - set = lonFilter2.getDocIdSet(context, acceptedDocs); - if (DocIdSets.isEmpty(set)) { - if (main == null) { - return null; - } else { - // nothing to do here, we remain with the main one - } - } else { - if (main == null) { - main = (FixedBitSet) set; - } else { - main.or((FixedBitSet) set); - } - } - - set = latFilter.getDocIdSet(context, acceptedDocs); - if (DocIdSets.isEmpty(set)) { - return null; - } - main.and(set.iterator()); - return main; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - WestGeoBoundingBoxFilter that = (WestGeoBoundingBoxFilter) o; - - if (latFilter != null ? !latFilter.equals(that.latFilter) : that.latFilter != null) return false; - if (lonFilter1 != null ? !lonFilter1.equals(that.lonFilter1) : that.lonFilter1 != null) return false; - if (lonFilter2 != null ? !lonFilter2.equals(that.lonFilter2) : that.lonFilter2 != null) return false; - - return true; - } - - @Override - public int hashCode() { - int result = lonFilter1 != null ? lonFilter1.hashCode() : 0; - result = 31 * result + (lonFilter2 != null ? lonFilter2.hashCode() : 0); - result = 31 * result + (latFilter != null ? latFilter.hashCode() : 0); - return result; - } + private static Filter westGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) { + XBooleanFilter filter = new XBooleanFilter(); + 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.latMapper().rangeFilter(bottomRight.lat(), topLeft.lat(), true, true), Occur.MUST); + return filter; } - static class EastGeoBoundingBoxFilter extends Filter { - - final Filter lonFilter; - final Filter latFilter; - - public EastGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) { - lonFilter = fieldMapper.lonMapper().rangeFilter(topLeft.lon(), bottomRight.lon(), true, true); - latFilter = fieldMapper.latMapper().rangeFilter(bottomRight.lat(), topLeft.lat(), true, true); - } - - @Override - public FixedBitSet getDocIdSet(AtomicReaderContext context, Bits acceptedDocs) throws IOException { - FixedBitSet main; - DocIdSet set = lonFilter.getDocIdSet(context, acceptedDocs); - if (DocIdSets.isEmpty(set)) { - return null; - } - main = (FixedBitSet) set; - set = latFilter.getDocIdSet(context, acceptedDocs); - if (DocIdSets.isEmpty(set)) { - return null; - } - main.and(set.iterator()); - return main; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - EastGeoBoundingBoxFilter that = (EastGeoBoundingBoxFilter) o; - - if (latFilter != null ? !latFilter.equals(that.latFilter) : that.latFilter != null) return false; - if (lonFilter != null ? !lonFilter.equals(that.lonFilter) : that.lonFilter != null) return false; - - return true; - } - - @Override - public int hashCode() { - int result = lonFilter != null ? lonFilter.hashCode() : 0; - result = 31 * result + (latFilter != null ? latFilter.hashCode() : 0); - return result; - } + private static Filter eastGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) { + XBooleanFilter filter = new XBooleanFilter(); + 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); + return filter; } }