| /* |
| * 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. |
| */ |
| |
| /** |
| * Support for index-time and query-time joins. |
| * <h2>Index-time joins</h2> |
| * |
| * <p>The index-time joining support joins while searching, where joined |
| * documents are indexed as a single document block using |
| * {@link org.apache.lucene.index.IndexWriter#addDocuments IndexWriter.addDocuments()}. |
| * This is useful for any normalized content (XML documents or database tables). In database terms, all rows for all |
| * joined tables matching a single row of the primary table must be |
| * indexed as a single document block, with the parent document |
| * being last in the group.</p> |
| * |
| * <p>When you index in this way, the documents in your index are divided |
| * into parent documents (the last document of each block) and child |
| * documents (all others). You provide a {@link org.apache.lucene.search.join.BitSetProducer} that identifies the |
| * parent documents, as Lucene does not currently record any information |
| * about doc blocks.</p> |
| * |
| * <p>At search time, use {@link |
| * org.apache.lucene.search.join.ToParentBlockJoinQuery} to remap/join |
| * matches from any child {@link org.apache.lucene.search.Query} (ie, a |
| * query that matches only child documents) up to the parent document |
| * space. The |
| * resulting query can then be used as a clause in any query that |
| * matches parent.</p> |
| * |
| * <p>If you care about what child documents matched for each parent document, |
| * then use the {@link org.apache.lucene.search.join.ParentChildrenBlockJoinQuery} query to |
| * per matched parent document retrieve the child documents that caused to match the |
| * parent document in first place. This query should be used after your main query |
| * has been executed. For each hit execute the the |
| * {@link org.apache.lucene.search.join.ParentChildrenBlockJoinQuery} query </p> |
| * <pre class="prettyprint"> |
| * TopDocs results = searcher.search(mainQuery, 10); |
| * for (int i = 0; i < results.scoreDocs.length; i++) { |
| * ScoreDoc scoreDoc = results.scoreDocs[i]; |
| * |
| * // Run ParentChildrenBlockJoinQuery to figure out the top matching child docs: |
| * ParentChildrenBlockJoinQuery parentChildrenBlockJoinQuery = |
| * new ParentChildrenBlockJoinQuery(parentFilter, childQuery, scoreDoc.doc); |
| * TopDocs topChildResults = searcher.search(parentChildrenBlockJoinQuery, 3); |
| * // Process top child hits... |
| * } |
| * </pre> |
| * |
| * <p>To map/join in the opposite direction, use {@link |
| * org.apache.lucene.search.join.ToChildBlockJoinQuery}. This wraps |
| * any query matching parent documents, creating the joined query |
| * matching only child documents. |
| * |
| * <h2>Query-time joins</h2> |
| * |
| * <p> |
| * The query time joining is index term based and implemented as two pass search. The first pass collects all the terms from a fromField |
| * that match the fromQuery. The second pass returns all documents that have matching terms in a toField to the terms |
| * collected in the first pass. |
| * </p> |
| * <p>Query time joining has the following input:</p> |
| * <ul> |
| * <li><code>fromField</code>: The from field to join from. |
| * <li><code>fromQuery</code>: The query executed to collect the from terms. This is usually the user specified query. |
| * <li><code>multipleValuesPerDocument</code>: Whether the fromField contains more than one value per document |
| * <li><code>scoreMode</code>: Defines how scores are translated to the other join side. If you don't care about scoring |
| * use {@link org.apache.lucene.search.join.ScoreMode#None} mode. This will disable scoring and is therefore more |
| * efficient (requires less memory and is faster). |
| * <li><code>toField</code>: The to field to join to |
| * </ul> |
| * <p> |
| * Basically the query-time joining is accessible from one static method. The user of this method supplies the method |
| * with the described input and a <code>IndexSearcher</code> where the from terms need to be collected from. The returned |
| * query can be executed with the same <code>IndexSearcher</code>, but also with another <code>IndexSearcher</code>. |
| * Example usage of the {@link org.apache.lucene.search.join.JoinUtil#createJoinQuery(String, boolean, String, org.apache.lucene.search.Query, org.apache.lucene.search.IndexSearcher, org.apache.lucene.search.join.ScoreMode) |
| * JoinUtil.createJoinQuery()} : |
| * </p> |
| * <pre class="prettyprint"> |
| * String fromField = "from"; // Name of the from field |
| * boolean multipleValuesPerDocument = false; // Set only to true in the case when your fromField has multiple values per document in your index |
| * String toField = "to"; // Name of the to field |
| * ScoreMode scoreMode = ScoreMode.Max; // Defines how the scores are translated into the other side of the join. |
| * Query fromQuery = new TermQuery(new Term("content", searchTerm)); // Query executed to collect from values to join to the to values |
| * |
| * Query joinQuery = JoinUtil.createJoinQuery(fromField, multipleValuesPerDocument, toField, fromQuery, fromSearcher, scoreMode); |
| * TopDocs topDocs = toSearcher.search(joinQuery, 10); // Note: toSearcher can be the same as the fromSearcher |
| * // Render topDocs... |
| * </pre> |
| */ |
| package org.apache.lucene.search.join; |