[MANUAL] English:
[zend.git] / documentation / manual / en / module_specs / Zend_Search_Lucene-QueryLanguage.xml
blob3dca2f9a252000c178e9fc99f9ecca5edc9d1093
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <sect1 id="zend.search.lucene.query-language">
4     <title>Query Language</title>
6     <para>
7         Java Lucene and <classname>Zend_Search_Lucene</classname> provide quite powerful query
8         languages.
9     </para>
11     <para>
12         These languages are mostly the same with some minor differences, which are mentioned below.
13     </para>
15     <para>
16         Full Java Lucene query language syntax documentation can be found
17         <ulink url="http://lucene.apache.org/java/2_3_0/queryparsersyntax.html">here</ulink>.
18     </para>
20     <sect2 id="zend.search.lucene.query-language.terms">
21         <title>Terms</title>
23         <para>
24             A query is broken up into terms and operators. There are three types of terms: Single
25             Terms, Phrases, and Subqueries.
26         </para>
28         <para>
29             A Single Term is a single word such as "test" or "hello".
30         </para>
32         <para>
33             A Phrase is a group of words surrounded by double quotes such as "hello dolly".
34         </para>
36         <para>
37             A Subquery is a query surrounded by parentheses such as "(hello dolly)".
38         </para>
40         <para>
41             Multiple terms can be combined together with boolean operators to form complex queries
42             (see below).
43         </para>
44     </sect2>
46     <sect2 id="zend.search.lucene.query-language.fields">
47         <title>Fields</title>
49         <para>
50             Lucene supports fields of data. When performing a search you can either specify a field,
51             or use the default field. The field names depend on indexed data and default field is
52             defined by current settings.
53         </para>
55         <para>
56             The first and most significant difference from Java Lucene is that terms are searched
57             through <emphasis>all fields</emphasis> by default.
58         </para>
60         <para>
61             There are two static methods in the <classname>Zend_Search_Lucene</classname> class
62             which allow the developer to configure these settings:
63         </para>
65         <programlisting language="php"><![CDATA[
66 $defaultSearchField = Zend_Search_Lucene::getDefaultSearchField();
67 ...
68 Zend_Search_Lucene::setDefaultSearchField('contents');
69 ]]></programlisting>
71         <para>
72             The <constant>NULL</constant> value indicated that the search is performed across all
73             fields. It's the default setting.
74         </para>
76         <para>
77             You can search specific fields by typing the field name followed by a colon ":" followed
78             by the term you are looking for.
79         </para>
81         <para>
82             As an example, let's assume a Lucene index contains two fields- title and text- with
83             text as the default field. If you want to find the document entitled "The Right Way"
84             which contains the text "don't go this way", you can enter:
85         </para>
87         <programlisting language="querystring"><![CDATA[
88 title:"The Right Way" AND text:go
89 ]]></programlisting>
91         <para>
92             or
93         </para>
95         <programlisting language="querystring"><![CDATA[
96 title:"Do it right" AND go
97 ]]></programlisting>
99         <para>
100             Because "text" is the default field, the field indicator is not required.
101         </para>
103         <para>
104             Note: The field is only valid for the term, phrase or subquery that it directly
105             precedes, so the query
107             <programlisting language="querystring"><![CDATA[
108 title:Do it right
109 ]]></programlisting>
111             Will only find "Do" in the title field. It will find "it" and "right" in the default
112             field (if the default field is set) or in all indexed fields (if the default field is
113             set to <constant>NULL</constant>).
114         </para>
115     </sect2>
117     <sect2 id="zend.search.lucene.query-language.wildcard">
118         <title>Wildcards</title>
120         <para>
121             Lucene supports single and multiple character wildcard searches within single terms (but
122             not within phrase queries).
123         </para>
125         <para>
126             To perform a single character wildcard search use the "?" symbol.
127         </para>
129         <para>
130             To perform a multiple character wildcard search use the "*" symbol.
131         </para>
133         <para>
134             The single character wildcard search looks for string that match the term with the "?"
135             replaced by any single character. For example, to search for "text" or "test" you can
136             use the search:
138             <programlisting language="querystring"><![CDATA[
139 te?t
140 ]]></programlisting>
141         </para>
143         <para>
144             Multiple character wildcard searches look for 0 or more characters when matching strings
145             against terms. For example, to search for test, tests or tester, you can use the search:
147             <programlisting language="querystring"><![CDATA[
148 test*
149 ]]></programlisting>
150         </para>
152         <para>
153             You can use "?", "*" or both at any place of the term:
155             <programlisting language="querystring"><![CDATA[
156 *wr?t*
157 ]]></programlisting>
159             It searches for "write", "wrote", "written", "rewrite", "rewrote" and so on.
160         </para>
162         <para>
163             Starting from ZF 1.7.7 wildcard patterns need some non-wildcard prefix. Default prefix
164             length is 3 (like in Java Lucene). So "*", "te?t", "*wr?t*" terms will cause an
165             exception
167             <footnote>
168                 <para>
169                     Please note, that it's not a
170                     <code>Zend_Search_Lucene_Search_QueryParserException</code>, but a
171                     <code>Zend_Search_Lucene_Exception</code>. It's thrown during query rewrite
172                     (execution) operation.
173                 </para>
174             </footnote>.
175         </para>
177         <para>
178             It can be altered using
179             <code>Zend_Search_Lucene_Search_Query_Wildcard::getMinPrefixLength()</code> and
180             <code>Zend_Search_Lucene_Search_Query_Wildcard::setMinPrefixLength()</code> methods.
181         </para>
182     </sect2>
184     <sect2 id="zend.search.lucene.query-language.modifiers">
185         <title>Term Modifiers</title>
187         <para>
188             Lucene supports modifying query terms to provide a wide range of searching options.
189         </para>
191         <para>
192             "~" modifier can be used to specify proximity search for phrases or fuzzy search for
193             individual terms.
194         </para>
195     </sect2>
197     <sect2 id="zend.search.lucene.query-language.range">
198         <title>Range Searches</title>
200         <para>
201             Range queries allow the developer or user to match documents whose field(s) values are
202             between the lower and upper bound specified by the range query. Range Queries can be
203             inclusive or exclusive of the upper and lower bounds. Sorting is performed
204             lexicographically.
206             <programlisting language="querystring"><![CDATA[
207 mod_date:[20020101 TO 20030101]
208 ]]></programlisting>
210             This will find documents whose mod_date fields have values between 20020101 and
211             20030101, inclusive. Note that Range Queries are not reserved for date fields. You could
212             also use range queries with non-date fields:
214             <programlisting language="querystring"><![CDATA[
215 title:{Aida TO Carmen}
216 ]]></programlisting>
218             This will find all documents whose titles would be sorted between Aida and Carmen, but
219             not including Aida and Carmen.
220         </para>
222         <para>
223             Inclusive range queries are denoted by square brackets. Exclusive range queries are
224             denoted by curly brackets.
225         </para>
227         <para>
228             If field is not specified then <classname>Zend_Search_Lucene</classname> searches for
229             specified interval through all fields by default.
231             <programlisting language="querystring"><![CDATA[
232 {Aida TO Carmen}
233 ]]></programlisting>
234         </para>
235     </sect2>
237     <sect2 id="zend.search.lucene.query-language.fuzzy">
238         <title>Fuzzy Searches</title>
240         <para>
241             <classname>Zend_Search_Lucene</classname> as well as Java Lucene supports fuzzy searches
242             based on the Levenshtein Distance, or Edit Distance algorithm. To do a fuzzy search use
243             the tilde, "~", symbol at the end of a Single word Term. For example to search for a
244             term similar in spelling to "roam" use the fuzzy search:
246             <programlisting language="querystring"><![CDATA[
247 roam~
248 ]]></programlisting>
250             This search will find terms like foam and roams. Additional (optional) parameter can
251             specify the required similarity. The value is between 0 and 1, with a value closer to 1
252             only terms with a higher similarity will be matched. For example:
254             <programlisting language="querystring"><![CDATA[
255 roam~0.8
256 ]]></programlisting>
258             The default that is used if the parameter is not given is 0.5.
259         </para>
260     </sect2>
262     <sect2 id="zend.search.lucene.query-language.matched-terms-limitations">
263         <title>Matched terms limitation</title>
265         <para>
266             Wildcard, range and fuzzy search queries may match too many terms. It may cause
267             incredible search performance downgrade.
268         </para>
270         <para>
271             So Zend_Search_Lucene sets a limit of matching terms per query (subquery). This limit
272             can be retrieved and set using
273             <code>Zend_Search_Lucene::getTermsPerQueryLimit()</code>/<code>Zend_Search_Lucene::setTermsPerQueryLimit($limit)</code>
274             methods.
275         </para>
277         <para>
278             Default matched terms per query limit is 1024.
279         </para>
280     </sect2>
282     <sect2 id="zend.search.lucene.query-language.proximity-search">
283         <title>Proximity Searches</title>
285         <para>
286             Lucene supports finding words from a phrase that are within a specified word distance in
287             a string. To do a proximity search use the tilde, "~", symbol at the end of the phrase.
288             For example to search for a "Zend" and "Framework" within 10 words of each other in a
289             document use the search:
291             <programlisting language="querystring"><![CDATA[
292 "Zend Framework"~10
293 ]]></programlisting>
294         </para>
295     </sect2>
297     <sect2 id="zend.search.lucene.query-language.boosting">
298         <title>Boosting a Term</title>
300         <para>
301             Java Lucene and <classname>Zend_Search_Lucene</classname> provide the relevance level of
302             matching documents based on the terms found. To boost the relevance of a term use the
303             caret, "^", symbol with a boost factor (a number) at the end of the term you are
304             searching. The higher the boost factor, the more relevant the term will be.
305         </para>
307         <para>
308             Boosting allows you to control the relevance of a document by boosting individual terms.
309             For example, if you are searching for
311             <programlisting language="querystring"><![CDATA[
312 PHP framework
313 ]]></programlisting>
315             and you want the term "PHP" to be more relevant boost it using the ^ symbol along with
316             the boost factor next to the term. You would type:
318             <programlisting language="querystring"><![CDATA[
319 PHP^4 framework
320 ]]></programlisting>
322             This will make documents with the term <acronym>PHP</acronym> appear more relevant. You
323             can also boost phrase terms and subqueries as in the example:
325             <programlisting language="querystring"><![CDATA[
326 "PHP framework"^4 "Zend Framework"
327 ]]></programlisting>
329             By default, the boost factor is 1. Although the boost factor must be positive,
330             it may be less than 1 (e.g. 0.2).
331         </para>
332     </sect2>
334     <sect2 id="zend.search.lucene.query-language.boolean">
335         <title>Boolean Operators</title>
337         <para>
338             Boolean operators allow terms to be combined through logic operators.
339             Lucene supports AND, "+", OR, NOT and "-" as Boolean operators.
340             Java Lucene requires boolean operators to be ALL CAPS.
341             <classname>Zend_Search_Lucene</classname> does not.
342         </para>
344         <para>
345             AND, OR, and NOT operators and "+", "-" defines two different styles to construct
346             boolean queries. Unlike Java Lucene, <classname>Zend_Search_Lucene</classname> doesn't
347             allow these two styles to be mixed.
348         </para>
350         <para>
351             If the AND/OR/NOT style is used, then an AND or OR operator must be present between all
352             query terms. Each term may also be preceded by NOT operator. The AND operator has higher
353             precedence than the OR operator. This differs from Java Lucene behavior.
354         </para>
356         <sect3 id="zend.search.lucene.query-language.boolean.and">
357             <title>AND</title>
359             <para>
360                 The AND operator means that all terms in the "AND group" must match some part of the
361                 searched field(s).
362             </para>
364             <para>
365                 To search for documents that contain "PHP framework" and "Zend Framework" use the
366                 query:
368                 <programlisting language="querystring"><![CDATA[
369 "PHP framework" AND "Zend Framework"
370 ]]></programlisting>
371             </para>
372         </sect3>
374         <sect3 id="zend.search.lucene.query-language.boolean.or">
375             <title>OR</title>
377             <para>
378                 The OR operator divides the query into several optional terms.
379             </para>
381             <para>
382                 To search for documents that contain "PHP framework" or "Zend Framework" use the
383                 query:
385                 <programlisting language="querystring"><![CDATA[
386 "PHP framework" OR "Zend Framework"
387 ]]></programlisting>
388             </para>
389         </sect3>
391         <sect3 id="zend.search.lucene.query-language.boolean.not">
392             <title>NOT</title>
394             <para>
395                 The NOT operator excludes documents that contain the term after NOT. But an "AND
396                 group" which contains only terms with the NOT operator gives an empty result set
397                 instead of a full set of indexed documents.
398             </para>
400             <para>
401                 To search for documents that contain "PHP framework" but not "Zend Framework" use
402                 the query:
404                 <programlisting language="querystring"><![CDATA[
405 "PHP framework" AND NOT "Zend Framework"
406 ]]></programlisting>
407             </para>
408         </sect3>
410         <sect3 id="zend.search.lucene.query-language.boolean.other-form">
411             <title>&amp;&amp;, ||, and ! operators</title>
413             <para>
414                 &amp;&amp;, ||, and ! may be used instead of AND, OR, and NOT notation.
415             </para>
416         </sect3>
418         <sect3 id="zend.search.lucene.query-language.boolean.plus">
419             <title>+</title>
421             <para>
422                 The "+" or required operator stipulates that the term after the "+" symbol must
423                 match the document.
424             </para>
426             <para>
427                 To search for documents that must contain "Zend" and may contain "Framework" use the
428                 query:
430                 <programlisting language="querystring"><![CDATA[
431 +Zend Framework
432 ]]></programlisting>
433             </para>
434         </sect3>
436         <sect3 id="zend.search.lucene.query-language.boolean.minus">
437             <title>-</title>
439             <para>
440                 The "-" or prohibit operator excludes documents that match the term after the "-"
441                 symbol.
442             </para>
444             <para>
445                 To search for documents that contain "PHP framework" but not "Zend Framework" use
446                 the query:
448                 <programlisting language="querystring"><![CDATA[
449 "PHP framework" -"Zend Framework"
450 ]]></programlisting>
451             </para>
452         </sect3>
454         <sect3 id="zend.search.lucene.query-language.boolean.no-operator">
455             <title>No Operator</title>
457             <para>
458                 If no operator is used, then the search behavior is defined by the "default boolean
459                 operator".
460             </para>
462             <para>
463                 This is set to <code>OR</code> by default.
464             </para>
466             <para>
467                 That implies each term is optional by default. It may or may not be present within
468                 document, but documents with this term will receive a higher score.
469             </para>
471             <para>
472                 To search for documents that requires "PHP framework" and may contain "Zend
473                 Framework" use the query:
475                 <programlisting language="querystring"><![CDATA[
476 +"PHP framework" "Zend Framework"
477 ]]></programlisting>
478             </para>
480             <para>
481                 The default boolean operator may be set or retrieved with the
482                 <classname>Zend_Search_Lucene_Search_QueryParser::setDefaultOperator($operator)</classname>
483                 and
484                 <classname>Zend_Search_Lucene_Search_QueryParser::getDefaultOperator()</classname>
485                 methods, respectively.
486             </para>
488             <para>
489                 These methods operate with the
490                 <classname>Zend_Search_Lucene_Search_QueryParser::B_AND</classname> and
491                 <classname>Zend_Search_Lucene_Search_QueryParser::B_OR</classname> constants.
492             </para>
493         </sect3>
494     </sect2>
496     <sect2 id="zend.search.lucene.query-language.grouping">
497         <title>Grouping</title>
499         <para>
500             Java Lucene and <classname>Zend_Search_Lucene</classname> support using parentheses to
501             group clauses to form sub queries. This can be useful if you want to control the
502             precedence of boolean logic operators for a query or mix different boolean query styles:
504             <programlisting language="querystring"><![CDATA[
505 +(framework OR library) +php
506 ]]></programlisting>
507             <classname>Zend_Search_Lucene</classname> supports subqueries nested to any level.
508         </para>
509     </sect2>
511     <sect2 id="zend.search.lucene.query-language.field-grouping">
512         <title>Field Grouping</title>
514         <para>
515             Lucene also supports using parentheses to group multiple clauses to a single field.
516         </para>
518         <para>
519             To search for a title that contains both the word "return" and the phrase "pink panther"
520             use the query:
522             <programlisting language="querystring"><![CDATA[
523 title:(+return +"pink panther")
524 ]]></programlisting>
525         </para>
526     </sect2>
528     <sect2 id="zend.search.lucene.query-language.escaping">
529         <title>Escaping Special Characters</title>
531         <para>
532             Lucene supports escaping special characters that are used in query syntax. The current
533             list of special characters is:
534         </para>
536         <para>
537             + - &amp;&amp; || ! ( ) { } [ ] ^ " ~ * ? : \
538         </para>
540         <para>
541             + and - inside single terms are automatically treated as common characters.
542         </para>
544         <para>
545             For other instances of these characters use the \ before each special character you'd
546             like to escape. For example to search for (1+1):2 use the query:
548             <programlisting language="querystring"><![CDATA[
549 \(1\+1\)\:2
550 ]]></programlisting>
551         </para>
552     </sect2>
553 </sect1>