lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mikemcc...@apache.org
Subject svn commit: r1685540 - in /lucene/dev/trunk: lucene/ lucene/analysis/common/src/java/org/apache/lucene/collation/ lucene/analysis/common/src/test/org/apache/lucene/collation/ lucene/analysis/icu/src/java/org/apache/lucene/collation/ lucene/analysis/icu...
Date Mon, 15 Jun 2015 11:01:14 GMT
Author: mikemccand
Date: Mon Jun 15 11:01:14 2015
New Revision: 1685540

URL: http://svn.apache.org/r1685540
Log:
LUCENE-6539: Add DocValuesNumbersQuery

Added:
    lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesNumbersQuery.java
  (with props)
    lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesRangeQuery.java
      - copied, changed from r1685539, lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/DocValuesRangeQuery.java
    lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesTermsQuery.java
      - copied, changed from r1684422, lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/DocValuesTermsQuery.java
    lucene/dev/trunk/lucene/sandbox/src/test/org/apache/lucene/search/TestDocValuesNumbersQuery.java
  (with props)
    lucene/dev/trunk/lucene/sandbox/src/test/org/apache/lucene/search/TestDocValuesRangeQuery.java
      - copied unchanged from r1684422, lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestDocValuesRangeQuery.java
    lucene/dev/trunk/lucene/sandbox/src/test/org/apache/lucene/search/TestDocValuesTermsQuery.java
      - copied unchanged from r1684422, lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestDocValuesTermsQuery.java
    lucene/dev/trunk/lucene/sandbox/src/test/org/apache/lucene/search/TestFieldCacheTermsFilter.java
      - copied unchanged from r1684422, lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestFieldCacheTermsFilter.java
Removed:
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/DocValuesRangeQuery.java
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/DocValuesTermsQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestDocValuesRangeQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestDocValuesTermsQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestFieldCacheTermsFilter.java
Modified:
    lucene/dev/trunk/lucene/CHANGES.txt
    lucene/dev/trunk/lucene/analysis/common/src/java/org/apache/lucene/collation/CollationDocValuesField.java
    lucene/dev/trunk/lucene/analysis/common/src/test/org/apache/lucene/collation/TestCollationDocValuesField.java
    lucene/dev/trunk/lucene/analysis/icu/src/java/org/apache/lucene/collation/ICUCollationDocValuesField.java
    lucene/dev/trunk/lucene/analysis/icu/src/test/org/apache/lucene/collation/TestICUCollationDocValuesField.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestComplexExplanations.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestSimpleExplanations.java
    lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/BaseExplanationTestCase.java
    lucene/dev/trunk/solr/common-build.xml

Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1685540&r1=1685539&r2=1685540&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Mon Jun 15 11:01:14 2015
@@ -75,6 +75,13 @@ New Features
 * LUCENE-6504: Add Lucene53Codec, with norms implemented directly
   via the Directory's RandomAccessInput api. (Robert Muir)
 
+* LUCENE-6539: Add new DocValuesNumbersQuery, to match any document
+  containing one of the specified long values.  This change also
+  moves the existing DocValuesTermsQuery and DocValuesRangeQuery
+  to Lucene's sandbox module, since in general these queries are
+  quite slow and are only fast in specific cases.  (Adrien Grand,
+  Robert Muir, Mike McCandless)
+
 API Changes
 
 * LUCENE-6508: Simplify Lock api, there is now just 

Modified: lucene/dev/trunk/lucene/analysis/common/src/java/org/apache/lucene/collation/CollationDocValuesField.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/analysis/common/src/java/org/apache/lucene/collation/CollationDocValuesField.java?rev=1685540&r1=1685539&r2=1685540&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/analysis/common/src/java/org/apache/lucene/collation/CollationDocValuesField.java
(original)
+++ lucene/dev/trunk/lucene/analysis/common/src/java/org/apache/lucene/collation/CollationDocValuesField.java
Mon Jun 15 11:01:14 2015
@@ -21,7 +21,6 @@ import java.text.Collator;
 
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.SortedDocValuesField;
-import org.apache.lucene.search.DocValuesRangeQuery;
 import org.apache.lucene.util.BytesRef;
 
 /**
@@ -29,7 +28,7 @@ import org.apache.lucene.util.BytesRef;
  * <p>
  * This is more efficient that {@link CollationKeyAnalyzer} if the field 
  * only has one value: no uninversion is necessary to sort on the field, 
- * locale-sensitive range queries can still work via {@link DocValuesRangeQuery}, 
+ * locale-sensitive range queries can still work via {@code DocValuesRangeQuery}, 
  * and the underlying data structures built at index-time are likely more efficient 
  * and use less memory than FieldCache.
  */

Modified: lucene/dev/trunk/lucene/analysis/common/src/test/org/apache/lucene/collation/TestCollationDocValuesField.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/analysis/common/src/test/org/apache/lucene/collation/TestCollationDocValuesField.java?rev=1685540&r1=1685539&r2=1685540&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/analysis/common/src/test/org/apache/lucene/collation/TestCollationDocValuesField.java
(original)
+++ lucene/dev/trunk/lucene/analysis/common/src/test/org/apache/lucene/collation/TestCollationDocValuesField.java
Mon Jun 15 11:01:14 2015
@@ -17,22 +17,16 @@ package org.apache.lucene.collation;
  * limitations under the License.
  */
 
-import java.text.Collator;
-import java.util.Locale;
-
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.StringField;
 import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.MultiDocValues;
 import org.apache.lucene.index.RandomIndexWriter;
-import org.apache.lucene.search.BooleanClause.Occur;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.DocValuesRangeQuery;
+import org.apache.lucene.index.SortedDocValues;
+import org.apache.lucene.index.StoredDocument;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchAllDocsQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.QueryUtils;
-import org.apache.lucene.search.ScoreDoc;
 import org.apache.lucene.search.Sort;
 import org.apache.lucene.search.SortField;
 import org.apache.lucene.search.TopDocs;
@@ -41,6 +35,9 @@ import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.TestUtil;
 
+import java.text.Collator;
+import java.util.Locale;
+
 /**
  * trivial test of CollationDocValuesField
  */
@@ -110,8 +107,7 @@ public class TestCollationDocValuesField
         String end = TestUtil.randomSimpleString(random());
         BytesRef lowerVal = new BytesRef(collator.getCollationKey(start).toByteArray());
         BytesRef upperVal = new BytesRef(collator.getCollationKey(end).toByteArray());
-        Query query = DocValuesRangeQuery.newBytesRefRange("collated", lowerVal, upperVal,
true, true);
-        doTestRanges(is, start, end, query, collator);
+        doTestRanges(is, start, end, lowerVal, upperVal, collator);
       }
     } finally {
       ir.close();
@@ -119,25 +115,15 @@ public class TestCollationDocValuesField
     }
   }
   
-  private void doTestRanges(IndexSearcher is, String startPoint, String endPoint, Query query,
Collator collator) throws Exception { 
-    QueryUtils.check(query);
-    
-    // positive test
-    TopDocs docs = is.search(query, is.getIndexReader().maxDoc());
-    for (ScoreDoc doc : docs.scoreDocs) {
-      String value = is.doc(doc.doc).get("field");
-      assertTrue(collate(collator, value, startPoint) >= 0);
-      assertTrue(collate(collator, value, endPoint) <= 0);
-    }
-    
-    // negative test
-    BooleanQuery bq = new BooleanQuery();
-    bq.add(new MatchAllDocsQuery(), Occur.SHOULD);
-    bq.add(query, Occur.MUST_NOT);
-    docs = is.search(bq, is.getIndexReader().maxDoc());
-    for (ScoreDoc doc : docs.scoreDocs) {
-      String value = is.doc(doc.doc).get("field");
-      assertTrue(collate(collator, value, startPoint) < 0 || collate(collator, value,
endPoint) > 0);
+  private void doTestRanges(IndexSearcher is, String startPoint, String endPoint, BytesRef
startBR, BytesRef endBR, Collator collator) throws Exception { 
+    SortedDocValues dvs = MultiDocValues.getSortedValues(is.getIndexReader(), "collated");
+    for(int docID=0;docID<is.getIndexReader().maxDoc();docID++) {
+      StoredDocument doc = is.doc(docID);
+      String s = doc.getField("field").stringValue();
+      boolean collatorAccepts = collator.compare(s, startPoint) >= 0 && collator.compare(s,
endPoint) <= 0;
+      BytesRef br = dvs.get(docID);
+      boolean luceneAccepts = br.compareTo(startBR) >= 0 && br.compareTo(endBR)
<= 0;
+      assertEquals(collatorAccepts, luceneAccepts);
     }
   }
 }

Modified: lucene/dev/trunk/lucene/analysis/icu/src/java/org/apache/lucene/collation/ICUCollationDocValuesField.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/analysis/icu/src/java/org/apache/lucene/collation/ICUCollationDocValuesField.java?rev=1685540&r1=1685539&r2=1685540&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/analysis/icu/src/java/org/apache/lucene/collation/ICUCollationDocValuesField.java
(original)
+++ lucene/dev/trunk/lucene/analysis/icu/src/java/org/apache/lucene/collation/ICUCollationDocValuesField.java
Mon Jun 15 11:01:14 2015
@@ -19,7 +19,6 @@ package org.apache.lucene.collation;
 
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.SortedDocValuesField;
-import org.apache.lucene.search.DocValuesRangeQuery;
 import org.apache.lucene.util.BytesRef;
 
 import com.ibm.icu.text.Collator;
@@ -30,7 +29,7 @@ import com.ibm.icu.text.RawCollationKey;
  * <p>
  * This is more efficient that {@link ICUCollationKeyAnalyzer} if the field 
  * only has one value: no uninversion is necessary to sort on the field, 
- * locale-sensitive range queries can still work via {@link DocValuesRangeQuery}, 
+ * locale-sensitive range queries can still work via {@code DocValuesRangeQuery}, 
  * and the underlying data structures built at index-time are likely more efficient 
  * and use less memory than FieldCache.
  */

Modified: lucene/dev/trunk/lucene/analysis/icu/src/test/org/apache/lucene/collation/TestICUCollationDocValuesField.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/analysis/icu/src/test/org/apache/lucene/collation/TestICUCollationDocValuesField.java?rev=1685540&r1=1685539&r2=1685540&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/analysis/icu/src/test/org/apache/lucene/collation/TestICUCollationDocValuesField.java
(original)
+++ lucene/dev/trunk/lucene/analysis/icu/src/test/org/apache/lucene/collation/TestICUCollationDocValuesField.java
Mon Jun 15 11:01:14 2015
@@ -21,15 +21,12 @@ import org.apache.lucene.document.Docume
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.StringField;
 import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.MultiDocValues;
 import org.apache.lucene.index.RandomIndexWriter;
-import org.apache.lucene.search.BooleanClause.Occur;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.DocValuesRangeQuery;
+import org.apache.lucene.index.SortedDocValues;
+import org.apache.lucene.index.StoredDocument;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchAllDocsQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.QueryUtils;
-import org.apache.lucene.search.ScoreDoc;
 import org.apache.lucene.search.Sort;
 import org.apache.lucene.search.SortField;
 import org.apache.lucene.search.TopDocs;
@@ -108,33 +105,22 @@ public class TestICUCollationDocValuesFi
       String end = TestUtil.randomSimpleString(random());
       BytesRef lowerVal = new BytesRef(collator.getCollationKey(start).toByteArray());
       BytesRef upperVal = new BytesRef(collator.getCollationKey(end).toByteArray());
-      Query query = DocValuesRangeQuery.newBytesRefRange("collated", lowerVal, upperVal,
true, true);
-      doTestRanges(is, start, end, query, collator);
+      doTestRanges(is, start, end, lowerVal, upperVal, collator);
     }
     
     ir.close();
     dir.close();
   }
   
-  private void doTestRanges(IndexSearcher is, String startPoint, String endPoint, Query query,
Collator collator) throws Exception { 
-    QueryUtils.check(query);
-    
-    // positive test
-    TopDocs docs = is.search(query, is.getIndexReader().maxDoc());
-    for (ScoreDoc doc : docs.scoreDocs) {
-      String value = is.doc(doc.doc).get("field");
-      assertTrue(collator.compare(value, startPoint) >= 0);
-      assertTrue(collator.compare(value, endPoint) <= 0);
-    }
-    
-    // negative test
-    BooleanQuery bq = new BooleanQuery();
-    bq.add(new MatchAllDocsQuery(), Occur.SHOULD);
-    bq.add(query, Occur.MUST_NOT);
-    docs = is.search(bq, is.getIndexReader().maxDoc());
-    for (ScoreDoc doc : docs.scoreDocs) {
-      String value = is.doc(doc.doc).get("field");
-      assertTrue(collator.compare(value, startPoint) < 0 || collator.compare(value, endPoint)
> 0);
+  private void doTestRanges(IndexSearcher is, String startPoint, String endPoint, BytesRef
startBR, BytesRef endBR, Collator collator) throws Exception { 
+    SortedDocValues dvs = MultiDocValues.getSortedValues(is.getIndexReader(), "collated");
+    for(int docID=0;docID<is.getIndexReader().maxDoc();docID++) {
+      StoredDocument doc = is.doc(docID);
+      String s = doc.getField("field").stringValue();
+      boolean collatorAccepts = collator.compare(s, startPoint) >= 0 && collator.compare(s,
endPoint) <= 0;
+      BytesRef br = dvs.get(docID);
+      boolean luceneAccepts = br.compareTo(startBR) >= 0 && br.compareTo(endBR)
<= 0;
+      assertEquals(collatorAccepts, luceneAccepts);
     }
   }
 }

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestComplexExplanations.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestComplexExplanations.java?rev=1685540&r1=1685539&r2=1685540&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestComplexExplanations.java
(original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestComplexExplanations.java
Mon Jun 15 11:01:14 2015
@@ -73,11 +73,11 @@ public class TestComplexExplanations ext
           Occur.SHOULD);
 
     Query t = new FilteredQuery(new TermQuery(new Term(FIELD, "xx")),
-                                new QueryWrapperFilter(new ItemizedQuery(new int[] {1,3})));
+                                new QueryWrapperFilter(matchTheseItems(new int[] {1,3})));
     t.setBoost(1000);
     q.add(t, Occur.SHOULD);
     
-    t = new ConstantScoreQuery(new ItemizedQuery(new int[] {0,2}));
+    t = new ConstantScoreQuery(matchTheseItems(new int[] {0,2}));
     t.setBoost(30);
     q.add(t, Occur.SHOULD);
     
@@ -136,11 +136,11 @@ public class TestComplexExplanations ext
           Occur.SHOULD);
     
     Query t = new FilteredQuery(new TermQuery(new Term(FIELD, "xx")),
-                                new QueryWrapperFilter(new ItemizedQuery(new int[] {1,3})));
+                                new QueryWrapperFilter(matchTheseItems(new int[] {1,3})));
     t.setBoost(1000);
     q.add(t, Occur.SHOULD);
     
-    t = new ConstantScoreQuery(new ItemizedQuery(new int[] {0,2}));
+    t = new ConstantScoreQuery(matchTheseItems(new int[] {0,2}));
     t.setBoost(-20.0f);
     q.add(t, Occur.SHOULD);
     
@@ -207,11 +207,11 @@ public class TestComplexExplanations ext
   public void testFQ5() throws Exception {
     TermQuery query = new TermQuery(new Term(FIELD, "xx"));
     query.setBoost(0);
-    bqtest(new FilteredQuery(query, new QueryWrapperFilter(new ItemizedQuery(new int[] {1,3}))),
new int[] {3});
+    bqtest(new FilteredQuery(query, new QueryWrapperFilter(matchTheseItems(new int[] {1,3}))),
new int[] {3});
   }
   
   public void testCSQ4() throws Exception {
-    Query q = new ConstantScoreQuery(new ItemizedQuery(new int[] {3}));
+    Query q = new ConstantScoreQuery(matchTheseItems(new int[] {3}));
     q.setBoost(0);
     bqtest(q, new int[] {3});
   }

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestSimpleExplanations.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestSimpleExplanations.java?rev=1685540&r1=1685539&r2=1685540&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestSimpleExplanations.java
(original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestSimpleExplanations.java
Mon Jun 15 11:01:14 2015
@@ -105,28 +105,28 @@ public class TestSimpleExplanations exte
   
   public void testFQ1() throws Exception {
     qtest(new FilteredQuery(new TermQuery(new Term(FIELD, "w1")),
-                            new QueryWrapperFilter(new ItemizedQuery(new int[] {0,1,2,3}))),
+                            new QueryWrapperFilter(matchTheseItems(new int[] {0,1,2,3}))),
           new int[] {0,1,2,3});
   }
   public void testFQ2() throws Exception {
     qtest(new FilteredQuery(new TermQuery(new Term(FIELD, "w1")),
-                            new QueryWrapperFilter(new ItemizedQuery(new int[] {0,2,3}))),
+                            new QueryWrapperFilter(matchTheseItems(new int[] {0,2,3}))),
           new int[] {0,2,3});
   }
   public void testFQ3() throws Exception {
     qtest(new FilteredQuery(new TermQuery(new Term(FIELD, "xx")),
-                            new QueryWrapperFilter(new ItemizedQuery(new int[] {1,3}))),
+                            new QueryWrapperFilter(matchTheseItems(new int[] {1,3}))),
           new int[] {3});
   }
   public void testFQ4() throws Exception {
     TermQuery termQuery = new TermQuery(new Term(FIELD, "xx"));
     termQuery.setBoost(1000);
-    qtest(new FilteredQuery(termQuery, new QueryWrapperFilter(new ItemizedQuery(new int[]
{1,3}))),
+    qtest(new FilteredQuery(termQuery, new QueryWrapperFilter(matchTheseItems(new int[] {1,3}))),
           new int[] {3});
   }
   public void testFQ6() throws Exception {
     Query q = new FilteredQuery(new TermQuery(new Term(FIELD, "xx")),
-                                new QueryWrapperFilter(new ItemizedQuery(new int[] {1,3})));
+                                new QueryWrapperFilter(matchTheseItems(new int[] {1,3})));
     q.setBoost(1000);
     qtest(q, new int[] {3});
   }
@@ -134,15 +134,15 @@ public class TestSimpleExplanations exte
   /* ConstantScoreQueries */
   
   public void testCSQ1() throws Exception {
-    Query q = new ConstantScoreQuery(new ItemizedQuery(new int[] {0,1,2,3}));
+    Query q = new ConstantScoreQuery(matchTheseItems(new int[] {0,1,2,3}));
     qtest(q, new int[] {0,1,2,3});
   }
   public void testCSQ2() throws Exception {
-    Query q = new ConstantScoreQuery(new ItemizedQuery(new int[] {1,3}));
+    Query q = new ConstantScoreQuery(matchTheseItems(new int[] {1,3}));
     qtest(q, new int[] {1,3});
   }
   public void testCSQ3() throws Exception {
-    Query q = new ConstantScoreQuery(new ItemizedQuery(new int[] {0,2}));
+    Query q = new ConstantScoreQuery(matchTheseItems(new int[] {0,2}));
     q.setBoost(1000);
     qtest(q, new int[] {0,2});
   }

Added: lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesNumbersQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesNumbersQuery.java?rev=1685540&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesNumbersQuery.java
(added)
+++ lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesNumbersQuery.java
Mon Jun 15 11:01:14 2015
@@ -0,0 +1,122 @@
+package org.apache.lucene.search;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.
+ */
+
+import org.apache.lucene.document.NumericDocValuesField;
+import org.apache.lucene.document.SortedNumericDocValuesField;
+import org.apache.lucene.index.DocValues;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.SortedNumericDocValues;
+import org.apache.lucene.util.Bits;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Like {@link DocValuesTermsQuery}, but this query only
+ * runs on a long {@link NumericDocValuesField} or a
+ * {@link SortedNumericDocValuesField}, matching
+ * all documents whose value in the specified field is
+ * contained in the provided set of long values.
+ *
+ * <p>
+ * <b>NOTE</b>: be very careful using this query: it is
+ * typically much slower than using {@code TermsQuery},
+ * but in certain specialized cases may be faster.
+ *
+ * @lucene.experimental
+ */
+public class DocValuesNumbersQuery extends Query {
+
+  private final String field;
+  private final Set<Long> numbers;
+
+  public DocValuesNumbersQuery(String field, Set<Long> numbers) {
+    this.field = Objects.requireNonNull(field);
+    this.numbers = Objects.requireNonNull(numbers, "Set of numbers must not be null");
+  }
+
+  public DocValuesNumbersQuery(String field, Long... numbers) {
+    this(field, new HashSet<Long>(Arrays.asList(numbers)));
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (!super.equals(obj)) {
+      return false;
+    }
+    // super.equals ensures we are the same class:
+    DocValuesNumbersQuery that = (DocValuesNumbersQuery) obj;
+    if (!field.equals(that.field)) {
+      return false;
+    }
+    return numbers.equals(that.numbers);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(field, numbers, getBoost());
+  }
+
+  @Override
+  public String toString(String defaultField) {
+    StringBuilder sb = new StringBuilder();
+    sb.append(field).append(": [");
+    for (Long number : numbers) {
+      sb.append(number).append(", ");
+    }
+    if (numbers.size() > 0) {
+      sb.setLength(sb.length() - 2);
+    }
+    return sb.append(']').toString();
+  }
+
+  @Override
+  public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException
{
+    return new RandomAccessWeight(this) {
+
+      @Override
+      protected Bits getMatchingDocs(LeafReaderContext context) throws IOException {
+         final SortedNumericDocValues values = DocValues.getSortedNumeric(context.reader(),
field);
+         return new Bits() {
+
+           @Override
+           public boolean get(int doc) {
+             values.setDocument(doc);
+             int count = values.count();
+             for(int i=0;i<count;i++) {
+               if (numbers.contains(values.valueAt(i))) {
+                 return true;
+               }
+             }
+
+             return false;
+          }
+
+          @Override
+          public int length() {
+            return context.reader().maxDoc();
+          }
+        };
+      }
+    };
+  }
+}

Copied: lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesRangeQuery.java
(from r1685539, lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/DocValuesRangeQuery.java)
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesRangeQuery.java?p2=lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesRangeQuery.java&p1=lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/DocValuesRangeQuery.java&r1=1685539&r2=1685540&rev=1685540&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/DocValuesRangeQuery.java
(original)
+++ lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesRangeQuery.java
Mon Jun 15 11:01:14 2015
@@ -35,6 +35,12 @@ import org.apache.lucene.util.ToStringUt
  * usually slow since they do not use an inverted index. However, in the
  * dense case where most documents match this query, it <b>might</b> be as
  * fast or faster than a regular {@link NumericRangeQuery}.
+ *
+ * <p>
+ * <b>NOTE</b>: be very careful using this query: it is
+ * typically much slower than using {@code TermsQuery},
+ * but in certain specialized cases may be faster.
+ *
  * @lucene.experimental
  */
 public final class DocValuesRangeQuery extends Query {

Copied: lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesTermsQuery.java
(from r1684422, lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/DocValuesTermsQuery.java)
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesTermsQuery.java?p2=lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesTermsQuery.java&p1=lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/DocValuesTermsQuery.java&r1=1684422&r2=1685540&rev=1685540&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/DocValuesTermsQuery.java
(original)
+++ lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesTermsQuery.java
Mon Jun 15 11:01:14 2015
@@ -45,6 +45,11 @@ import org.apache.lucene.util.LongBitSet
  * characteristics, as described below.
  *
  * <p>
+ * <b>NOTE</b>: be very careful using this query: it is
+ * typically much slower than using {@code TermsQuery},
+ * but in certain specialized cases may be faster.
+ *
+ * <p>
  * With each search, this query translates the specified
  * set of Terms into a private {@link LongBitSet} keyed by
  * term number per unique {@link IndexReader} (normally one
@@ -82,6 +87,8 @@ import org.apache.lucene.util.LongBitSet
  *
  * <p>
  * Which query is best is very application dependent.
+ *
+ * @lucene.experimental
  */
 public class DocValuesTermsQuery extends Query {
 

Added: lucene/dev/trunk/lucene/sandbox/src/test/org/apache/lucene/search/TestDocValuesNumbersQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/sandbox/src/test/org/apache/lucene/search/TestDocValuesNumbersQuery.java?rev=1685540&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/sandbox/src/test/org/apache/lucene/search/TestDocValuesNumbersQuery.java
(added)
+++ lucene/dev/trunk/lucene/sandbox/src/test/org/apache/lucene/search/TestDocValuesNumbersQuery.java
Mon Jun 15 11:01:14 2015
@@ -0,0 +1,194 @@
+package org.apache.lucene.search;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.
+ */
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field.Store;
+import org.apache.lucene.document.NumericDocValuesField;
+import org.apache.lucene.document.SortedNumericDocValuesField;
+import org.apache.lucene.document.StringField;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.RandomIndexWriter;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause.Occur;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.IOUtils;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.TestUtil;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class TestDocValuesNumbersQuery extends LuceneTestCase {
+
+  public void testEquals() {
+    assertEquals(new DocValuesNumbersQuery("field", 17L, 42L), new DocValuesNumbersQuery("field",
17L, 42L));
+    assertEquals(new DocValuesNumbersQuery("field", 17L, 42L, 32416190071L), new DocValuesNumbersQuery("field",
17L, 32416190071L, 42L));
+    assertFalse(new DocValuesNumbersQuery("field", 42L).equals(new DocValuesNumbersQuery("field2",
42L)));
+    assertFalse(new DocValuesNumbersQuery("field", 17L, 42L).equals(new DocValuesNumbersQuery("field",
17L, 32416190071L)));
+  }
+
+  public void testDuelTermsQuery() throws IOException {
+    final int iters = atLeast(2);
+    for (int iter = 0; iter < iters; ++iter) {
+      final List<Long> allNumbers = new ArrayList<>();
+      final int numNumbers = TestUtil.nextInt(random(), 1, 1 << TestUtil.nextInt(random(),
1, 10));
+      for (int i = 0; i < numNumbers; ++i) {
+        allNumbers.add(random().nextLong());
+      }
+      Directory dir = newDirectory();
+      RandomIndexWriter iw = new RandomIndexWriter(random(), dir);
+      final int numDocs = atLeast(100);
+      for (int i = 0; i < numDocs; ++i) {
+        Document doc = new Document();
+        final Long number = allNumbers.get(random().nextInt(allNumbers.size()));
+        doc.add(new StringField("text", number.toString(), Store.NO));
+        doc.add(new NumericDocValuesField("long", number));
+        doc.add(new SortedNumericDocValuesField("twolongs", number));
+        doc.add(new SortedNumericDocValuesField("twolongs", number*2));
+        iw.addDocument(doc);
+      }
+      if (numNumbers > 1 && random().nextBoolean()) {
+        iw.deleteDocuments(new TermQuery(new Term("text", allNumbers.get(0).toString())));
+      }
+      iw.commit();
+      final IndexReader reader = iw.getReader();
+      final IndexSearcher searcher = newSearcher(reader);
+      iw.close();
+
+      if (reader.numDocs() == 0) {
+        // may occasionally happen if all documents got the same term
+        IOUtils.close(reader, dir);
+        continue;
+      }
+
+      for (int i = 0; i < 100; ++i) {
+        final float boost = random().nextFloat() * 10;
+        final int numQueryNumbers = TestUtil.nextInt(random(), 1, 1 << TestUtil.nextInt(random(),
1, 8));
+        Set<Long> queryNumbers = new HashSet<>();
+        Set<Long> queryNumbersX2 = new HashSet<>();
+        for (int j = 0; j < numQueryNumbers; ++j) {
+          Long number = allNumbers.get(random().nextInt(allNumbers.size()));
+          queryNumbers.add(number);
+          queryNumbersX2.add(2*number);
+        }
+        final BooleanQuery bq = new BooleanQuery();
+        for (Long number : queryNumbers) {
+          bq.add(new TermQuery(new Term("text", number.toString())), Occur.SHOULD);
+        }
+        Query q1 = new ConstantScoreQuery(bq);
+        q1.setBoost(boost);
+
+        Query q2 = new DocValuesNumbersQuery("long", queryNumbers);
+        q2.setBoost(boost);
+        assertSameMatches(searcher, q1, q2, true);
+
+        Query q3 = new DocValuesNumbersQuery("twolongs", queryNumbers);
+        q3.setBoost(boost);
+        assertSameMatches(searcher, q1, q3, true);
+
+        Query q4 = new DocValuesNumbersQuery("twolongs", queryNumbersX2);
+        q4.setBoost(boost);
+        assertSameMatches(searcher, q1, q4, true);
+      }
+
+      reader.close();
+      dir.close();
+    }
+  }
+
+  public void testApproximation() throws IOException {
+    final int iters = atLeast(2);
+    for (int iter = 0; iter < iters; ++iter) {
+      final List<Long> allNumbers = new ArrayList<>();
+      final int numNumbers = TestUtil.nextInt(random(), 1, 1 << TestUtil.nextInt(random(),
1, 10));
+      for (int i = 0; i < numNumbers; ++i) {
+        allNumbers.add(random().nextLong());
+      }
+      Directory dir = newDirectory();
+      RandomIndexWriter iw = new RandomIndexWriter(random(), dir);
+      final int numDocs = atLeast(100);
+      for (int i = 0; i < numDocs; ++i) {
+        Document doc = new Document();
+        final Long number = allNumbers.get(random().nextInt(allNumbers.size()));
+        doc.add(new StringField("text", number.toString(), Store.NO));
+        doc.add(new NumericDocValuesField("long", number));
+        iw.addDocument(doc);
+      }
+      if (numNumbers > 1 && random().nextBoolean()) {
+        iw.deleteDocuments(new TermQuery(new Term("text", allNumbers.get(0).toString())));
+      }
+      iw.commit();
+      final IndexReader reader = iw.getReader();
+      final IndexSearcher searcher = newSearcher(reader);
+      iw.close();
+
+      if (reader.numDocs() == 0) {
+        // may occasionally happen if all documents got the same term
+        IOUtils.close(reader, dir);
+        continue;
+      }
+
+      for (int i = 0; i < 100; ++i) {
+        final float boost = random().nextFloat() * 10;
+        final int numQueryNumbers = TestUtil.nextInt(random(), 1, 1 << TestUtil.nextInt(random(),
1, 8));
+        Set<Long> queryNumbers = new HashSet<>();
+        for (int j = 0; j < numQueryNumbers; ++j) {
+          queryNumbers.add(allNumbers.get(random().nextInt(allNumbers.size())));
+        }
+        final BooleanQuery bq = new BooleanQuery();
+        for (Long number : queryNumbers) {
+          bq.add(new TermQuery(new Term("text", number.toString())), Occur.SHOULD);
+        }
+        Query q1 = new ConstantScoreQuery(bq);
+        q1.setBoost(boost);
+        final Query q2 = new DocValuesNumbersQuery("long", queryNumbers);
+        q2.setBoost(boost);
+
+        BooleanQuery bq1 = new BooleanQuery();
+        bq1.add(q1, Occur.MUST);
+        bq1.add(new TermQuery(new Term("text", allNumbers.get(0).toString())), Occur.FILTER);
+
+        BooleanQuery bq2 = new BooleanQuery();
+        bq2.add(q2, Occur.MUST);
+        bq2.add(new TermQuery(new Term("text", allNumbers.get(0).toString())), Occur.FILTER);
+
+        assertSameMatches(searcher, bq1, bq2, true);
+      }
+
+      reader.close();
+      dir.close();
+    }
+  }
+
+  private void assertSameMatches(IndexSearcher searcher, Query q1, Query q2, boolean scores)
throws IOException {
+    final int maxDoc = searcher.getIndexReader().maxDoc();
+    final TopDocs td1 = searcher.search(q1, maxDoc, scores ? Sort.RELEVANCE : Sort.INDEXORDER);
+    final TopDocs td2 = searcher.search(q2, maxDoc, scores ? Sort.RELEVANCE : Sort.INDEXORDER);
+    assertEquals(td1.totalHits, td2.totalHits);
+    for (int i = 0; i < td1.scoreDocs.length; ++i) {
+      assertEquals(td1.scoreDocs[i].doc, td2.scoreDocs[i].doc);
+      if (scores) {
+        assertEquals(td1.scoreDocs[i].score, td2.scoreDocs[i].score, 10e-7);
+      }
+    }
+  }
+}

Modified: lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/BaseExplanationTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/BaseExplanationTestCase.java?rev=1685540&r1=1685539&r2=1685540&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/BaseExplanationTestCase.java
(original)
+++ lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/BaseExplanationTestCase.java
Mon Jun 15 11:01:14 2015
@@ -112,19 +112,14 @@ public abstract class BaseExplanationTes
   }
   
   /** 
-   * Convenience subclass of FieldCacheTermsFilter
+   * Convenience subclass of TermsQuery
    */
-  public static class ItemizedQuery extends DocValuesTermsQuery {
-    private static String[] int2str(int [] terms) {
-      String [] out = new String[terms.length];
-      for (int i = 0; i < terms.length; i++) {
-        out[i] = ""+terms[i];
-      }
-      return out;
-    }
-    public ItemizedQuery(int [] keys) {
-      super(KEY, int2str(keys));
+  protected Query matchTheseItems(int[] terms) {
+    BooleanQuery query = new BooleanQuery();
+    for(int term : terms) {
+      query.add(new BooleanClause(new TermQuery(new Term(KEY, ""+term)), BooleanClause.Occur.SHOULD));
     }
+    return query;
   }
 
   /** helper for generating MultiPhraseQueries */

Modified: lucene/dev/trunk/solr/common-build.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/common-build.xml?rev=1685540&r1=1685539&r2=1685540&view=diff
==============================================================================
--- lucene/dev/trunk/solr/common-build.xml (original)
+++ lucene/dev/trunk/solr/common-build.xml Mon Jun 15 11:01:14 2015
@@ -103,6 +103,7 @@
     <pathelement location="${queries.jar}"/>
     <pathelement location="${queryparser.jar}"/>
     <pathelement location="${join.jar}"/>
+    <pathelement location="${sandbox.jar}"/>
   </path>
 
   <path id="solr.base.classpath">
@@ -168,7 +169,7 @@
 
   <target name="prep-lucene-jars" 
   	      depends="jar-lucene-core, jar-backward-codecs, jar-analyzers-phonetic, jar-analyzers-kuromoji,
jar-codecs,jar-expressions, jar-suggest, jar-highlighter, jar-memory,
-  	               jar-misc, jar-spatial, jar-grouping, jar-queries, jar-queryparser, jar-join">
+  	               jar-misc, jar-spatial, jar-grouping, jar-queries, jar-queryparser, jar-join,
jar-sandbox">
   	  <property name="solr.deps.compiled" value="true"/>
   </target>
 	



Mime
View raw message