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 2016/12/16 14:57:04 UTC

lucene-solr:master: LUCENE-7587: add helper FacetQuery and MultiFacetQuery classes to simplify drill down implementation

Repository: lucene-solr
Updated Branches:
  refs/heads/master 3b182aa2f -> 835296f20


LUCENE-7587: add helper FacetQuery and MultiFacetQuery classes to simplify drill down implementation


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/835296f2
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/835296f2
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/835296f2

Branch: refs/heads/master
Commit: 835296f20a17c12c66b4f043074c94e3ddd5c2b5
Parents: 3b182aa
Author: Mike McCandless <mi...@apache.org>
Authored: Fri Dec 16 09:56:51 2016 -0500
Committer: Mike McCandless <mi...@apache.org>
Committed: Fri Dec 16 09:56:51 2016 -0500

----------------------------------------------------------------------
 lucene/CHANGES.txt                              |  4 +
 .../org/apache/lucene/facet/FacetQuery.java     | 52 +++++++++++
 .../apache/lucene/facet/MultiFacetQuery.java    | 61 ++++++++++++
 .../org/apache/lucene/facet/TestFacetQuery.java | 98 ++++++++++++++++++++
 4 files changed, 215 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/835296f2/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 7e61469..47cd6e8 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -74,6 +74,10 @@ New features
 * LUCENE-7590: Added DocValuesStatsCollector to compute statistics on DocValues
   fields. (Shai Erera)
 
+* LUCENE-7587: The new FacetQuery and MultiFacetQuery helper classes
+  make it simpler to execute drill down when drill sideways counts are
+  not needed (Emmanuel Keller via Mike McCandless)
+
 Bug Fixes
 
 * LUCENE-7547: JapaneseTokenizerFactory was failing to close the

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/835296f2/lucene/facet/src/java/org/apache/lucene/facet/FacetQuery.java
----------------------------------------------------------------------
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/FacetQuery.java b/lucene/facet/src/java/org/apache/lucene/facet/FacetQuery.java
new file mode 100644
index 0000000..ec20292
--- /dev/null
+++ b/lucene/facet/src/java/org/apache/lucene/facet/FacetQuery.java
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.facet;
+
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TermQuery;
+
+/**
+ * A term {@link Query} over a {@link FacetField}.
+ * <p>
+ * <b>NOTE:</b>This helper class is an alternative to {@link DrillDownQuery}
+ * especially in cases where you don't intend to use {@link DrillSideways}
+ *
+ * @lucene.experimental
+ */
+public class FacetQuery extends TermQuery {
+
+  /**
+   * Creates a new {@code FacetQuery} filtering the query on the given dimension.
+   */
+  public FacetQuery(final FacetsConfig facetsConfig, final String dimension, final String... path) {
+    super(toTerm(facetsConfig.getDimConfig(dimension), dimension, path));
+  }
+
+  /**
+   * Creates a new {@code FacetQuery} filtering the query on the given dimension.
+   * <p>
+   * <b>NOTE:</b>Uses FacetsConfig.DEFAULT_DIM_CONFIG.
+   */
+  public FacetQuery(final String dimension, final String... path) {
+    super(toTerm(FacetsConfig.DEFAULT_DIM_CONFIG, dimension, path));
+  }
+
+  static Term toTerm(final FacetsConfig.DimConfig dimConfig, final String dimension, final String... path) {
+    return new Term(dimConfig.indexFieldName, FacetsConfig.pathToString(dimension, path));
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/835296f2/lucene/facet/src/java/org/apache/lucene/facet/MultiFacetQuery.java
----------------------------------------------------------------------
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/MultiFacetQuery.java b/lucene/facet/src/java/org/apache/lucene/facet/MultiFacetQuery.java
new file mode 100644
index 0000000..dd212c6
--- /dev/null
+++ b/lucene/facet/src/java/org/apache/lucene/facet/MultiFacetQuery.java
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.facet;
+
+import org.apache.lucene.index.Term;
+import org.apache.lucene.queries.TermsQuery;
+import org.apache.lucene.search.Query;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * A multi-terms {@link Query} over a {@link FacetField}.
+ * <p>
+ * <b>NOTE:</b>This helper class is an alternative to {@link DrillDownQuery}
+ * especially in cases where you don't intend to use {@link DrillSideways}
+ *
+ * @lucene.experimental
+ * @see org.apache.lucene.queries.TermsQuery
+ */
+public class MultiFacetQuery extends TermsQuery {
+
+  /**
+   * Creates a new {@code MultiFacetQuery} filtering the query on the given dimension.
+   */
+  public MultiFacetQuery(final FacetsConfig facetsConfig, final String dimension, final String[]... paths) {
+    super(toTerms(facetsConfig.getDimConfig(dimension), dimension, paths));
+  }
+
+  /**
+   * Creates a new {@code MultiFacetQuery} filtering the query on the given dimension.
+   * <p>
+   * <b>NOTE:</b>Uses FacetsConfig.DEFAULT_DIM_CONFIG.
+   */
+  public MultiFacetQuery(final String dimension, final String[]... paths) {
+    super(toTerms(FacetsConfig.DEFAULT_DIM_CONFIG, dimension, paths));
+  }
+
+  static Collection<Term> toTerms(final FacetsConfig.DimConfig dimConfig, final String dimension,
+          final String[]... paths) {
+    final Collection<Term> terms = new ArrayList<>(paths.length);
+    for (String[] path : paths)
+      terms.add(FacetQuery.toTerm(dimConfig, dimension, path));
+    return terms;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/835296f2/lucene/facet/src/test/org/apache/lucene/facet/TestFacetQuery.java
----------------------------------------------------------------------
diff --git a/lucene/facet/src/test/org/apache/lucene/facet/TestFacetQuery.java b/lucene/facet/src/test/org/apache/lucene/facet/TestFacetQuery.java
new file mode 100644
index 0000000..f3aa079
--- /dev/null
+++ b/lucene/facet/src/test/org/apache/lucene/facet/TestFacetQuery.java
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+package org.apache.lucene.facet;
+
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.analysis.MockTokenizer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.TextField;
+import org.apache.lucene.facet.sortedset.SortedSetDocValuesFacetField;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexableField;
+import org.apache.lucene.index.RandomIndexWriter;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.IOUtils;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class TestFacetQuery extends FacetTestCase {
+
+  private static Directory indexDirectory;
+  private static RandomIndexWriter indexWriter;
+  private static IndexReader indexReader;
+  private static IndexSearcher searcher;
+  private static FacetsConfig config;
+
+  private static final IndexableField[] DOC_SINGLEVALUED =
+          new IndexableField[] { new SortedSetDocValuesFacetField("Author", "Mark Twain") };
+
+  private static final IndexableField[] DOC_MULTIVALUED =
+          new SortedSetDocValuesFacetField[] { new SortedSetDocValuesFacetField("Author", "Kurt Vonnegut") };
+
+  private static final IndexableField[] DOC_NOFACET =
+          new IndexableField[] { new TextField("Hello", "World", Field.Store.YES) };
+
+  @BeforeClass
+  public static void createTestIndex() throws IOException {
+    indexDirectory = newDirectory();
+    // create and open an index writer
+    indexWriter = new RandomIndexWriter(random(), indexDirectory,
+            newIndexWriterConfig(new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false)));
+
+    config = new FacetsConfig();
+
+    indexDocuments(DOC_SINGLEVALUED, DOC_MULTIVALUED, DOC_NOFACET);
+
+    indexReader = indexWriter.getReader();
+    // prepare searcher to search against
+    searcher = newSearcher(indexReader);
+  }
+
+  private static void indexDocuments(IndexableField[]... docs) throws IOException {
+    for (IndexableField[] fields : docs) {
+      for (IndexableField field : fields) {
+        Document doc = new Document();
+        doc.add(field);
+        indexWriter.addDocument(config.build(doc));
+      }
+    }
+  }
+
+  @AfterClass
+  public static void closeTestIndex() throws IOException {
+    IOUtils.close(indexReader, indexWriter, indexDirectory);
+  }
+
+  @Test
+  public void testSingleValued() throws Exception {
+    TopDocs topDocs = searcher.search(new FacetQuery("Author", "Mark Twain"), 10);
+    assertEquals(1, topDocs.totalHits);
+  }
+
+  @Test
+  public void testMultiValued() throws Exception {
+    TopDocs topDocs = searcher.search(
+            new MultiFacetQuery("Author", new String[] { "Mark Twain" }, new String[] { "Kurt Vonnegut" }), 10);
+    assertEquals(2, topDocs.totalHits);
+  }
+}