You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2015/06/15 12:22:16 UTC

svn commit: r1685526 - in /lucene/dev/trunk/lucene: CHANGES.txt sandbox/src/java/org/apache/lucene/bkdtree/BKDPointInBBoxQuery.java sandbox/src/test/org/apache/lucene/bkdtree/TestBKDTree.java

Author: mikemccand
Date: Mon Jun 15 10:22:16 2015
New Revision: 1685526

URL: http://svn.apache.org/r1685526
Log:
LUCENE-6560: BKDPointInBBOxQuery now handles dateline crossing correctly

Modified:
    lucene/dev/trunk/lucene/CHANGES.txt
    lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/bkdtree/BKDPointInBBoxQuery.java
    lucene/dev/trunk/lucene/sandbox/src/test/org/apache/lucene/bkdtree/TestBKDTree.java

Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1685526&r1=1685525&r2=1685526&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Mon Jun 15 10:22:16 2015
@@ -122,6 +122,9 @@ Bug fixes
 * LUCENE-6558: Highlighters now work with CustomScoreQuery (Cao Manh
   Dat via Mike McCandless)
 
+* LUCENE-6560: BKDPointInBBoxQuery now handles "dateline crossing"
+  correctly (Nick Knize, Mike McCandless)
+
 Changes in Runtime Behavior
 
 * LUCENE-6501: The subreader structure in ParallelCompositeReader

Modified: lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/bkdtree/BKDPointInBBoxQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/bkdtree/BKDPointInBBoxQuery.java?rev=1685526&r1=1685525&r2=1685526&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/bkdtree/BKDPointInBBoxQuery.java (original)
+++ lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/bkdtree/BKDPointInBBoxQuery.java Mon Jun 15 10:22:16 2015
@@ -17,13 +17,13 @@ package org.apache.lucene.bkdtree;
  * limitations under the License.
  */
 
-import java.io.IOException;
-import java.util.Set;
-
+import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.LeafReader;
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.index.SortedNumericDocValues;
 import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.Explanation;
@@ -34,6 +34,9 @@ import org.apache.lucene.search.Weight;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.ToStringUtils;
 
+import java.io.IOException;
+import java.util.Set;
+
 /** Finds all previously indexed points that fall within the specified boundings box.
  *
  *  <p>The field must be indexed with {@link BKDTreeDocValuesFormat}, and {@link BKDPointField} added per document.
@@ -163,6 +166,28 @@ public class BKDPointInBBoxQuery extends
       }
     };
   }
+
+  @Override
+  public Query rewrite(IndexReader reader) throws IOException {
+    // Crosses date line: we just rewrite into OR of two bboxes:
+    if (maxLon < minLon) {
+
+      // Disable coord here because a multi-valued doc could match both rects and get unfairly boosted:
+      BooleanQuery q = new BooleanQuery(true);
+
+      // E.g.: maxLon = -179, minLon = 179
+      BKDPointInBBoxQuery left = new BKDPointInBBoxQuery(field, minLat, maxLat, BKDTreeWriter.MIN_LON_INCL, maxLon);
+      left.setBoost(getBoost());
+      q.add(new BooleanClause(left, BooleanClause.Occur.SHOULD));
+      BKDPointInBBoxQuery right = new BKDPointInBBoxQuery(field, minLat, maxLat, minLon, BKDTreeWriter.MAX_LON_INCL);
+      right.setBoost(getBoost());
+      q.add(new BooleanClause(right, BooleanClause.Occur.SHOULD));
+      return q;
+    } else {
+      return this;
+    }
+  }
+
   @Override
   public int hashCode() {
     int hash = super.hashCode();

Modified: lucene/dev/trunk/lucene/sandbox/src/test/org/apache/lucene/bkdtree/TestBKDTree.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/sandbox/src/test/org/apache/lucene/bkdtree/TestBKDTree.java?rev=1685526&r1=1685525&r2=1685526&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/sandbox/src/test/org/apache/lucene/bkdtree/TestBKDTree.java (original)
+++ lucene/dev/trunk/lucene/sandbox/src/test/org/apache/lucene/bkdtree/TestBKDTree.java Mon Jun 15 10:22:16 2015
@@ -452,18 +452,27 @@ public class TestBKDTree extends LuceneT
                 lat1 = x;
               }
 
+              boolean crossesDateLine;
               if (lon1 < lon0) {
-                double x = lon0;
-                lon0 = lon1;
-                lon1 = x;
+                if (random().nextBoolean()) {
+                  double x = lon0;
+                  lon0 = lon1;
+                  lon1 = x;
+                  crossesDateLine = false;
+                } else {
+                  crossesDateLine = true;
+                }
+              } else {
+                crossesDateLine = false;
               }
 
               if (VERBOSE) {
-                System.out.println("\nTEST: iter=" + iter + " lat=" + lat0 + " TO " + lat1 + " lon=" + lon0 + " TO " + lon1);
+                System.out.println("\nTEST: iter=" + iter + " lat=" + lat0 + " TO " + lat1 + " lon=" + lon0 + " TO " + lon1 + " crossesDateLine=" + crossesDateLine);
               }
 
               Query query;
-              if (random().nextBoolean()) {
+              // TODO: get poly query working with dateline crossing too (how?)!
+              if (crossesDateLine || random().nextBoolean()) {
                 query = new BKDPointInBBoxQuery("point", lat0, lat1, lon0, lon1);
               } else {
                 double[] lats = new double[5];
@@ -522,7 +531,7 @@ public class TestBKDTree extends LuceneT
                     // The poly check quantizes slightly differently, so we allow for boundary cases to disagree
                   } else {
                     // We do exact quantized comparison so the bbox query should never disagree:
-                    fail(Thread.currentThread().getName() + ": iter=" + iter + " id=" + id + " docID=" + docID + " lat=" + lats[id] + " lon=" + lons[id] + " (bbox: lat=" + lat0 + " TO " + lat1 + " lon=" + lon0 + " TO " + lon1 + ") expected " + expected + " but got: " + hits.get(docID) + " deleted?=" + deleted.contains(id) + " query=" + query);
+                    fail(Thread.currentThread().getName() + ": iter=" + iter + " id=" + id + " docID=" + docID + " lat=" + lats[id] + " lon=" + lons[id] + " (bbox: lat=" + lat0 + " TO " + lat1 + " lon=" + lon0 + " TO " + lon1 + ") expected " + expected + " but got: " + hits.get(docID) + " deleted?=" + deleted.contains(id) + " query=" + query + " crossesDateLine=" + crossesDateLine);
                   }
                 }
               }
@@ -553,10 +562,18 @@ public class TestBKDTree extends LuceneT
     int pointLatEnc = BKDTreeWriter.encodeLat(pointLat);
     int pointLonEnc = BKDTreeWriter.encodeLon(pointLon);
 
-    return pointLatEnc >= rectLatMinEnc &&
-      pointLatEnc < rectLatMaxEnc &&
-      pointLonEnc >= rectLonMinEnc &&
-      pointLonEnc < rectLonMaxEnc;
+    if (rectLonMin < rectLonMax) {
+      return pointLatEnc >= rectLatMinEnc &&
+        pointLatEnc < rectLatMaxEnc &&
+        pointLonEnc >= rectLonMinEnc &&
+        pointLonEnc < rectLonMaxEnc;
+    } else {
+      // Rect crosses dateline:
+      return pointLatEnc >= rectLatMinEnc &&
+        pointLatEnc < rectLatMaxEnc &&
+        (pointLonEnc >= rectLonMinEnc ||
+         pointLonEnc < rectLonMaxEnc);
+    }
   }
 
   private static double randomLat() {