pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / contrib / queryparser / src / java / org / apache / lucene / queryParser / standard / MultiFieldQueryParserWrapper.java
1 package org.apache.lucene.queryParser.standard;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 import java.util.Map;
21
22 import org.apache.lucene.analysis.Analyzer;
23 import org.apache.lucene.queryParser.ParseException;
24 import org.apache.lucene.search.BooleanClause;
25 import org.apache.lucene.search.BooleanQuery;
26 import org.apache.lucene.search.Query;
27
28 /**
29  * This class behaves as the as the lucene 2.4 MultiFieldQueryParser class, but uses the new
30  * query parser interface instead of the old one. <br/>
31  * <br/>
32  * This class should be used when the new query parser features are needed and
33  * also keep at the same time the old query parser interface. <br/>
34  * 
35  * @deprecated this class will be removed soon, it's a temporary class to be
36  *             used along the transition from the old query parser to the new
37  *             one
38  */
39 @Deprecated
40 public class MultiFieldQueryParserWrapper extends QueryParserWrapper {
41
42   /**
43    * Creates a MultiFieldQueryParser. Allows passing of a map with term to
44    * Boost, and the boost to apply to each term.
45    * 
46    * <p>
47    * It will, when parse(String query) is called, construct a query like this
48    * (assuming the query consists of two terms and you specify the two fields
49    * <code>title</code> and <code>body</code>):
50    * </p>
51    * 
52    * <code>
53      * (title:term1 body:term1) (title:term2 body:term2)
54      * </code>
55    * 
56    * <p>
57    * When setDefaultOperator(AND_OPERATOR) is set, the result will be:
58    * </p>
59    * 
60    * <code>
61      * +(title:term1 body:term1) +(title:term2 body:term2)
62      * </code>
63    * 
64    * <p>
65    * When you pass a boost (title=>5 body=>10) you can get
66    * </p>
67    * 
68    * <code>
69      * +(title:term1^5.0 body:term1^10.0) +(title:term2^5.0 body:term2^10.0)
70      * </code>
71    * 
72    * <p>
73    * In other words, all the query's terms must appear, but it doesn't matter in
74    * what fields they appear.
75    * </p>
76    */
77 public MultiFieldQueryParserWrapper(String[] fields, Analyzer analyzer, Map<String, Float> boosts) {
78     this(fields, analyzer);
79     StandardQueryParser qpHelper = getQueryParserHelper();
80
81     qpHelper.setMultiFields(fields);
82     qpHelper.setFieldsBoost(boosts);
83
84   }
85
86   /**
87    * Creates a MultiFieldQueryParser.
88    * 
89    * <p>
90    * It will, when parse(String query) is called, construct a query like this
91    * (assuming the query consists of two terms and you specify the two fields
92    * <code>title</code> and <code>body</code>):
93    * </p>
94    * 
95    * <code>
96      * (title:term1 body:term1) (title:term2 body:term2)
97      * </code>
98    * 
99    * <p>
100    * When setDefaultOperator(AND_OPERATOR) is set, the result will be:
101    * </p>
102    * 
103    * <code>
104      * +(title:term1 body:term1) +(title:term2 body:term2)
105      * </code>
106    * 
107    * <p>
108    * In other words, all the query's terms must appear, but it doesn't matter in
109    * what fields they appear.
110    * </p>
111    */
112   public MultiFieldQueryParserWrapper(String[] fields, Analyzer analyzer) {
113     super(null, analyzer);
114
115     StandardQueryParser qpHelper = getQueryParserHelper();
116     qpHelper.setAnalyzer(analyzer);
117
118     qpHelper.setMultiFields(fields);
119   }
120
121   /**
122    * Parses a query which searches on the fields specified.
123    * <p>
124    * If x fields are specified, this effectively constructs:
125    * 
126    * <pre>
127    * &lt;code&gt;
128    * (field1:query1) (field2:query2) (field3:query3)...(fieldx:queryx)
129    * &lt;/code&gt;
130    * </pre>
131    * 
132    * @param queries
133    *          Queries strings to parse
134    * @param fields
135    *          Fields to search on
136    * @param analyzer
137    *          Analyzer to use
138    * @throws ParseException
139    *           if query parsing fails
140    * @throws IllegalArgumentException
141    *           if the length of the queries array differs from the length of the
142    *           fields array
143    */
144   public static Query parse(String[] queries, String[] fields, Analyzer analyzer)
145       throws ParseException {
146     if (queries.length != fields.length)
147       throw new IllegalArgumentException("queries.length != fields.length");
148     BooleanQuery bQuery = new BooleanQuery();
149     for (int i = 0; i < fields.length; i++) {
150       QueryParserWrapper qp = new QueryParserWrapper(fields[i], analyzer);
151       Query q = qp.parse(queries[i]);
152       if (q != null && // q never null, just being defensive
153           (!(q instanceof BooleanQuery) || ((BooleanQuery) q).getClauses().length > 0)) {
154         bQuery.add(q, BooleanClause.Occur.SHOULD);
155       }
156     }
157     return bQuery;
158   }
159
160   /**
161    * Parses a query, searching on the fields specified. Use this if you need to
162    * specify certain fields as required, and others as prohibited.
163    * <p>
164    * 
165    * <pre>
166    * Usage:
167    * &lt;code&gt;
168    * String[] fields = {&quot;filename&quot;, &quot;contents&quot;, &quot;description&quot;};
169    * BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD,
170    *                BooleanClause.Occur.MUST,
171    *                BooleanClause.Occur.MUST_NOT};
172    * MultiFieldQueryParser.parse(&quot;query&quot;, fields, flags, analyzer);
173    * &lt;/code&gt;
174    * </pre>
175    *<p>
176    * The code above would construct a query:
177    * 
178    * <pre>
179    * &lt;code&gt;
180    * (filename:query) +(contents:query) -(description:query)
181    * &lt;/code&gt;
182    * </pre>
183    * 
184    * @param query
185    *          Query string to parse
186    * @param fields
187    *          Fields to search on
188    * @param flags
189    *          Flags describing the fields
190    * @param analyzer
191    *          Analyzer to use
192    * @throws ParseException
193    *           if query parsing fails
194    * @throws IllegalArgumentException
195    *           if the length of the fields array differs from the length of the
196    *           flags array
197    */
198   public static Query parse(String query, String[] fields,
199       BooleanClause.Occur[] flags, Analyzer analyzer) throws ParseException {
200     if (fields.length != flags.length)
201       throw new IllegalArgumentException("fields.length != flags.length");
202     BooleanQuery bQuery = new BooleanQuery();
203     for (int i = 0; i < fields.length; i++) {
204       QueryParserWrapper qp = new QueryParserWrapper(fields[i], analyzer);
205       Query q = qp.parse(query);
206       if (q != null && // q never null, just being defensive
207           (!(q instanceof BooleanQuery) || ((BooleanQuery) q).getClauses().length > 0)) {
208         bQuery.add(q, flags[i]);
209       }
210     }
211     return bQuery;
212   }
213
214   /**
215    * Parses a query, searching on the fields specified. Use this if you need to
216    * specify certain fields as required, and others as prohibited.
217    * <p>
218    * 
219    * <pre>
220    * Usage:
221    * &lt;code&gt;
222    * String[] query = {&quot;query1&quot;, &quot;query2&quot;, &quot;query3&quot;};
223    * String[] fields = {&quot;filename&quot;, &quot;contents&quot;, &quot;description&quot;};
224    * BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD,
225    *                BooleanClause.Occur.MUST,
226    *                BooleanClause.Occur.MUST_NOT};
227    * MultiFieldQueryParser.parse(query, fields, flags, analyzer);
228    * &lt;/code&gt;
229    * </pre>
230    *<p>
231    * The code above would construct a query:
232    * 
233    * <pre>
234    * &lt;code&gt;
235    * (filename:query1) +(contents:query2) -(description:query3)
236    * &lt;/code&gt;
237    * </pre>
238    * 
239    * @param queries
240    *          Queries string to parse
241    * @param fields
242    *          Fields to search on
243    * @param flags
244    *          Flags describing the fields
245    * @param analyzer
246    *          Analyzer to use
247    * @throws ParseException
248    *           if query parsing fails
249    * @throws IllegalArgumentException
250    *           if the length of the queries, fields, and flags array differ
251    */
252   public static Query parse(String[] queries, String[] fields,
253       BooleanClause.Occur[] flags, Analyzer analyzer) throws ParseException {
254     if (!(queries.length == fields.length && queries.length == flags.length))
255       throw new IllegalArgumentException(
256           "queries, fields, and flags array have have different length");
257     BooleanQuery bQuery = new BooleanQuery();
258     for (int i = 0; i < fields.length; i++) {
259       QueryParserWrapper qp = new QueryParserWrapper(fields[i], analyzer);
260       Query q = qp.parse(queries[i]);
261       if (q != null && // q never null, just being defensive
262           (!(q instanceof BooleanQuery) || ((BooleanQuery) q).getClauses().length > 0)) {
263         bQuery.add(q, flags[i]);
264       }
265     }
266     return bQuery;
267   }
268
269 }