lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sh...@apache.org
Subject svn commit: r1416864 - in /lucene/dev/branches/branch_4x: ./ lucene/ lucene/facet/ lucene/facet/src/examples/org/apache/lucene/facet/example/simple/ lucene/facet/src/java/org/apache/lucene/facet/search/ lucene/facet/src/test/org/apache/lucene/facet/sea...
Date Tue, 04 Dec 2012 10:21:21 GMT
Author: shaie
Date: Tue Dec  4 10:21:18 2012
New Revision: 1416864

URL: http://svn.apache.org/viewvc?rev=1416864&view=rev
Log:
LUCENE-4580: Facet DrillDown should return a ConstantScoreQuery

Modified:
    lucene/dev/branches/branch_4x/   (props changed)
    lucene/dev/branches/branch_4x/lucene/   (props changed)
    lucene/dev/branches/branch_4x/lucene/CHANGES.txt   (contents, props changed)
    lucene/dev/branches/branch_4x/lucene/facet/   (props changed)
    lucene/dev/branches/branch_4x/lucene/facet/src/examples/org/apache/lucene/facet/example/simple/SimpleSearcher.java
    lucene/dev/branches/branch_4x/lucene/facet/src/java/org/apache/lucene/facet/search/DrillDown.java
    lucene/dev/branches/branch_4x/lucene/facet/src/test/org/apache/lucene/facet/search/DrillDownTest.java

Modified: lucene/dev/branches/branch_4x/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/CHANGES.txt?rev=1416864&r1=1416863&r2=1416864&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/CHANGES.txt (original)
+++ lucene/dev/branches/branch_4x/lucene/CHANGES.txt Tue Dec  4 10:21:18 2012
@@ -238,6 +238,9 @@ Optimizations
   Users of this API can now simply obtain an instance via DocValues#getDirectSource per thread.
   (Simon Willnauer)
 
+* LUCENE-4580: DrillDown.query variants return a ConstantScoreQuery with boost set to 0.0f
+  so that documents scores are not affected by running a drill-down query. (Shai Erera)
+  
 Documentation
 
 * LUCENE-4483: Refer to BytesRef.deepCopyOf in Term's constructor that takes BytesRef.

Modified: lucene/dev/branches/branch_4x/lucene/facet/src/examples/org/apache/lucene/facet/example/simple/SimpleSearcher.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/facet/src/examples/org/apache/lucene/facet/example/simple/SimpleSearcher.java?rev=1416864&r1=1416863&r2=1416864&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/facet/src/examples/org/apache/lucene/facet/example/simple/SimpleSearcher.java
(original)
+++ lucene/dev/branches/branch_4x/lucene/facet/src/examples/org/apache/lucene/facet/example/simple/SimpleSearcher.java
Tue Dec  4 10:21:18 2012
@@ -138,6 +138,8 @@ public class SimpleSearcher {
   public static List<FacetResult> searchWithDrillDown(IndexReader indexReader,
       TaxonomyReader taxoReader) throws Exception {
 
+    final FacetIndexingParams indexingParams = new DefaultFacetIndexingParams();
+    
     // base query the user is interested in
     Query baseQuery = new TermQuery(new Term(SimpleUtils.TEXT, "white"));
 
@@ -145,7 +147,7 @@ public class SimpleSearcher {
     CountFacetRequest facetRequest = new CountFacetRequest(new CategoryPath("root","a"),
10);
     
     // initial search - all docs matching the base query will contribute to the accumulation

-    List<FacetResult> res1 = searchWithRequest(indexReader, taxoReader, null, facetRequest);
+    List<FacetResult> res1 = searchWithRequest(indexReader, taxoReader, indexingParams,
facetRequest);
     
     // a single result (because there was a single request) 
     FacetResult fres = res1.get(0);
@@ -157,12 +159,12 @@ public class SimpleSearcher {
     CategoryPath categoryOfInterest = resIterator.next().getLabel();
     
     // drill-down preparation: turn the base query into a drill-down query for the category
of interest
-    Query q2 = DrillDown.query(baseQuery, categoryOfInterest);
+    Query q2 = DrillDown.query(indexingParams, baseQuery, categoryOfInterest);
     
     // that's it - search with the new query and we're done!
     // only documents both matching the base query AND containing the 
     // category of interest will contribute to the new accumulation
-    return searchWithRequestAndQuery(q2, indexReader, taxoReader, null, facetRequest);
+    return searchWithRequestAndQuery(q2, indexReader, taxoReader, indexingParams, facetRequest);
   }
   
 }

Modified: lucene/dev/branches/branch_4x/lucene/facet/src/java/org/apache/lucene/facet/search/DrillDown.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/facet/src/java/org/apache/lucene/facet/search/DrillDown.java?rev=1416864&r1=1416863&r2=1416864&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/facet/src/java/org/apache/lucene/facet/search/DrillDown.java
(original)
+++ lucene/dev/branches/branch_4x/lucene/facet/src/java/org/apache/lucene/facet/search/DrillDown.java
Tue Dec  4 10:21:18 2012
@@ -2,6 +2,7 @@ package org.apache.lucene.facet.search;
 
 import org.apache.lucene.index.Term;
 import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.ConstantScoreQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.search.BooleanClause.Occur;
@@ -29,7 +30,14 @@ import org.apache.lucene.facet.taxonomy.
  */
 
 /**
- * Creation of drill down term or query.
+ * Utility class for creating drill-down {@link Query queries} or {@link Term
+ * terms} over {@link CategoryPath}. This can be used to e.g. narrow down a
+ * user's search to selected categories.
+ * <p>
+ * <b>NOTE:</b> if you choose to create your own {@link Query} by calling
+ * {@link #term}, it is recommended to wrap it with {@link ConstantScoreQuery}
+ * and set the {@link ConstantScoreQuery#setBoost(float) boost} to {@code 0.0f},
+ * so that it does not affect the scores of the documents.
  * 
  * @lucene.experimental
  */
@@ -42,9 +50,7 @@ public final class DrillDown {
     return term(sParams.getFacetIndexingParams(), path);
   }
 
-  /**
-   * Return a term for drilling down into a category.
-   */
+  /** Return a drill-down {@link Term} for a category. */
   public static final Term term(FacetIndexingParams iParams, CategoryPath path) {
     CategoryListParams clp = iParams.getCategoryListParams(path);
     char[] buffer = new char[path.charsNeededForFullPath()];
@@ -53,58 +59,51 @@ public final class DrillDown {
   }
   
   /**
-   * Return a query for drilling down into all given categories (AND).
-   * @see #term(FacetSearchParams, CategoryPath)
-   * @see #query(FacetSearchParams, Query, CategoryPath...)
+   * Wraps a given {@link Query} as a drill-down query over the given
+   * categories, assuming all are required (e.g. {@code AND}). You can construct
+   * a query with different modes (such as {@code OR} or {@code AND} of
+   * {@code ORs}) by creating a {@link BooleanQuery} and call this method
+   * several times. Make sure to wrap the query in that case by
+   * {@link ConstantScoreQuery} and set the boost to 0.0f, so that it doesn't
+   * affect scoring.
+   * <p>
+   * <b>NOTE:</b> {@code baseQuery} can be {@code null}, in which case only the
+   * {@link Query} over the categories will is returned.
    */
-  public static final Query query(FacetIndexingParams iParams, CategoryPath... paths) {
-    if (paths==null || paths.length==0) {
+  public static final Query query(FacetIndexingParams iParams, Query baseQuery, CategoryPath...
paths) {
+    if (paths == null || paths.length == 0) {
       throw new IllegalArgumentException("Empty category path not allowed for drill down
query!");
     }
-    if (paths.length==1) {
-      return new TermQuery(term(iParams, paths[0]));
+    
+    final Query q;
+    if (paths.length == 1) {
+      q = new TermQuery(term(iParams, paths[0]));
+    } else {
+      BooleanQuery bq = new BooleanQuery(true); // disable coord
+      for (CategoryPath cp : paths) {
+        bq.add(new TermQuery(term(iParams, cp)), Occur.MUST);
+      }
+      q = bq;
     }
-    BooleanQuery res = new BooleanQuery();
-    for (CategoryPath cp : paths) {
-      res.add(new TermQuery(term(iParams, cp)), Occur.MUST);
-    }
-    return res;
-  }
-  
-  /**
-   * Return a query for drilling down into all given categories (AND).
-   * @see #term(FacetSearchParams, CategoryPath)
-   * @see #query(FacetSearchParams, Query, CategoryPath...)
-   */
-  public static final Query query(FacetSearchParams sParams, CategoryPath... paths) {
-    return query(sParams.getFacetIndexingParams(), paths);
-  }
 
-  /**
-   * Turn a base query into a drilling-down query for all given category paths (AND).
-   * @see #query(FacetIndexingParams, CategoryPath...)
-   */
-  public static final Query query(FacetIndexingParams iParams, Query baseQuery, CategoryPath...
paths) {
-    BooleanQuery res = new BooleanQuery();
-    res.add(baseQuery, Occur.MUST);
-    res.add(query(iParams, paths), Occur.MUST);
-    return res;
+    final ConstantScoreQuery drillDownQuery = new ConstantScoreQuery(q);
+    drillDownQuery.setBoost(0.0f);
+
+    if (baseQuery == null) {
+      return drillDownQuery;
+    } else {
+      BooleanQuery res = new BooleanQuery();
+      res.add(baseQuery, Occur.MUST);
+      res.add(drillDownQuery, Occur.MUST);
+      return res;
+    }
   }
 
   /**
-   * Turn a base query into a drilling-down query for all given category paths (AND).
-   * @see #query(FacetSearchParams, CategoryPath...)
+   * @see #query(FacetIndexingParams, Query, CategoryPath...)
    */
   public static final Query query(FacetSearchParams sParams, Query baseQuery, CategoryPath...
paths) {
     return query(sParams.getFacetIndexingParams(), baseQuery, paths);
   }
 
-  /**
-   * Turn a base query into a drilling-down query using the default {@link FacetSearchParams}
 
-   * @see #query(FacetSearchParams, Query, CategoryPath...)
-   */
-  public static final Query query(Query baseQuery, CategoryPath... paths) {
-    return query(new FacetSearchParams(), baseQuery, paths);
-  }
-
 }

Modified: lucene/dev/branches/branch_4x/lucene/facet/src/test/org/apache/lucene/facet/search/DrillDownTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/facet/src/test/org/apache/lucene/facet/search/DrillDownTest.java?rev=1416864&r1=1416863&r2=1416864&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/facet/src/test/org/apache/lucene/facet/search/DrillDownTest.java
(original)
+++ lucene/dev/branches/branch_4x/lucene/facet/src/test/org/apache/lucene/facet/search/DrillDownTest.java
Tue Dec  4 10:21:18 2012
@@ -8,28 +8,28 @@ import org.apache.lucene.analysis.MockTo
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.TextField;
+import org.apache.lucene.facet.index.CategoryDocumentBuilder;
+import org.apache.lucene.facet.index.params.CategoryListParams;
+import org.apache.lucene.facet.index.params.PerDimensionIndexingParams;
+import org.apache.lucene.facet.search.params.FacetSearchParams;
+import org.apache.lucene.facet.taxonomy.CategoryPath;
+import org.apache.lucene.facet.taxonomy.TaxonomyWriter;
+import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
+import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.RandomIndexWriter;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreDoc;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.search.TopDocs;
 import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.LuceneTestCase;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.facet.index.CategoryDocumentBuilder;
-import org.apache.lucene.facet.index.params.CategoryListParams;
-import org.apache.lucene.facet.index.params.PerDimensionIndexingParams;
-import org.apache.lucene.facet.search.params.FacetSearchParams;
-import org.apache.lucene.facet.taxonomy.CategoryPath;
-import org.apache.lucene.facet.taxonomy.TaxonomyWriter;
-import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
-import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter;
-
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -128,7 +128,7 @@ public class DrillDownTest extends Lucen
     IndexSearcher searcher = newSearcher(reader);
 
     // Making sure the query yields 25 documents with the facet "a"
-    Query q = DrillDown.query(defaultParams, new CategoryPath("a"));
+    Query q = DrillDown.query(defaultParams, null, new CategoryPath("a"));
     TopDocs docs = searcher.search(q, 100);
     assertEquals(25, docs.totalHits);
     
@@ -139,7 +139,7 @@ public class DrillDownTest extends Lucen
     assertEquals(5, docs.totalHits);
 
     // Making sure that a query of both facet "a" and facet "b" yields 5 results
-    Query q3 = DrillDown.query(defaultParams, new CategoryPath("a"), new CategoryPath("b"));
+    Query q3 = DrillDown.query(defaultParams, null, new CategoryPath("a"), new CategoryPath("b"));
     docs = searcher.search(q3, 100);
     assertEquals(5, docs.totalHits);
     
@@ -156,18 +156,18 @@ public class DrillDownTest extends Lucen
     IndexSearcher searcher = newSearcher(reader);
 
     // Create the base query to start with
-    Query q = DrillDown.query(defaultParams, new CategoryPath("a"));
+    Query q = DrillDown.query(defaultParams, null, new CategoryPath("a"));
     
     // Making sure the query yields 5 documents with the facet "b" and the
     // previous (facet "a") query as a base query
-    Query q2 = DrillDown.query(q, new CategoryPath("b"));
+    Query q2 = DrillDown.query(defaultParams, q, new CategoryPath("b"));
     TopDocs docs = searcher.search(q2, 100);
     assertEquals(5, docs.totalHits);
 
     // Check that content:foo (which yields 50% results) and facet/b (which yields 20%)
     // would gather together 10 results (10%..) 
     Query fooQuery = new TermQuery(new Term("content", "foo"));
-    Query q4 = DrillDown.query(fooQuery, new CategoryPath("b"));
+    Query q4 = DrillDown.query(defaultParams, fooQuery, new CategoryPath("b"));
     docs = searcher.search(q4, 100);
     assertEquals(10, docs.totalHits);
   }
@@ -187,5 +187,38 @@ public class DrillDownTest extends Lucen
     dir.close();
     taxoDir.close();
   }
+  
+  @Test
+  public void testScoring() throws IOException {
+    // verify that drill-down queries do not modify scores
+    IndexSearcher searcher = newSearcher(reader);
+
+    float[] scores = new float[reader.maxDoc()];
+    
+    Query q = new TermQuery(new Term("content", "foo"));
+    TopDocs docs = searcher.search(q, reader.maxDoc()); // fetch all available docs to this
query
+    for (ScoreDoc sd : docs.scoreDocs) {
+      scores[sd.doc] = sd.score;
+    }
+    
+    // create a drill-down query with category "a", scores should not change
+    q = DrillDown.query(defaultParams, q, new CategoryPath("a"));
+    docs = searcher.search(q, reader.maxDoc()); // fetch all available docs to this query
+    for (ScoreDoc sd : docs.scoreDocs) {
+      assertEquals("score of doc=" + sd.doc + " modified", scores[sd.doc], sd.score, 0f);
+    }
+  }
+  
+  @Test
+  public void testScoringNoBaseQuery() throws IOException {
+    // verify that drill-down queries (with no base query) returns 0.0 score
+    IndexSearcher searcher = newSearcher(reader);
+    
+    Query q = DrillDown.query(defaultParams, null, new CategoryPath("a"));
+    TopDocs docs = searcher.search(q, reader.maxDoc()); // fetch all available docs to this
query
+    for (ScoreDoc sd : docs.scoreDocs) {
+      assertEquals(0f, sd.score, 0f);
+    }
+  }
     
 }



Mime
View raw message