~slub.team/goobi-indexserver/3.x

« back to all changes in this revision

Viewing changes to lucene/contrib/icu/src/java/overview.html

  • Committer: Sebastian Meyer
  • Date: 2012-08-03 09:12:40 UTC
  • Revision ID: sebastian.meyer@slub-dresden.de-20120803091240-x6861b0vabq1xror
Remove Lucene and Solr source code and add patches instead
Fix Bug #985487: Auto-suggestion for the search interface

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<!--
2
 
 Licensed to the Apache Software Foundation (ASF) under one or more
3
 
 contributor license agreements.  See the NOTICE file distributed with
4
 
 this work for additional information regarding copyright ownership.
5
 
 The ASF licenses this file to You under the Apache License, Version 2.0
6
 
 (the "License"); you may not use this file except in compliance with
7
 
 the License.  You may obtain a copy of the License at
8
 
 
9
 
     http://www.apache.org/licenses/LICENSE-2.0
10
 
 
11
 
 Unless required by applicable law or agreed to in writing, software
12
 
 distributed under the License is distributed on an "AS IS" BASIS,
13
 
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 
 See the License for the specific language governing permissions and
15
 
 limitations under the License.
16
 
-->
17
 
<html>
18
 
  <head>
19
 
    <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
20
 
    <title>
21
 
      Apache Lucene ICU integration module
22
 
    </title>
23
 
  </head>
24
 
<body>
25
 
<p>
26
 
This module exposes functionality from 
27
 
<a href="http://site.icu-project.org/">ICU</a> to Apache Lucene. ICU4J is a Java
28
 
library that enhances Java's internationalization support by improving 
29
 
performance, keeping current with the Unicode Standard, and providing richer
30
 
APIs. This module exposes the following functionality:
31
 
</p>
32
 
<ul>
33
 
  <li><a href="#segmentation">Text Segmentation</a>: Tokenizes text based on 
34
 
  properties and rules defined in Unicode.</li>
35
 
  <li><a href="#collation">Collation</a>: Compare strings according to the 
36
 
  conventions and standards of a particular language, region or country.</li>
37
 
  <li><a href="#normalization">Normalization</a>: Converts text to a unique,
38
 
  equivalent form.</li>
39
 
  <li><a href="#casefolding">Case Folding</a>: Removes case distinctions with
40
 
  Unicode's Default Caseless Matching algorithm.</li>
41
 
  <li><a href="#searchfolding">Search Term Folding</a>: Removes distinctions
42
 
  (such as accent marks) between similar characters for a loose or fuzzy search.</li>
43
 
  <li><a href="#transform">Text Transformation</a>: Transforms Unicode text in
44
 
  a context-sensitive fashion: e.g. mapping Traditional to Simplified Chinese</li>
45
 
</ul>
46
 
<hr/>
47
 
<h1><a name="segmentation">Text Segmentation</a></h1>
48
 
<p>
49
 
Text Segmentation (Tokenization) divides document and query text into index terms
50
 
(typically words). Unicode provides special properties and rules so that this can
51
 
be done in a manner that works well with most languages.
52
 
</p>
53
 
<p>
54
 
Text Segmentation implements the word segmentation specified in
55
 
<a href="http://unicode.org/reports/tr29/">Unicode Text Segmentation</a>.
56
 
Additionally the algorithm can be tailored based on writing system, for example
57
 
text in the Thai script is automatically delegated to a dictionary-based segmentation 
58
 
algorithm.
59
 
</p>
60
 
<h2>Use Cases</h2>
61
 
<ul>
62
 
  <li>
63
 
    As a more thorough replacement for StandardTokenizer that works well for
64
 
    most languages. 
65
 
  </li>
66
 
</ul>
67
 
<h2>Example Usages</h2>
68
 
<h3>Tokenizing multilanguage text</h3>
69
 
<pre class="prettyprint">
70
 
  /**
71
 
   * This tokenizer will work well in general for most languages.
72
 
   */
73
 
  Tokenizer tokenizer = new ICUTokenizer(reader);
74
 
</pre>
75
 
<hr/>
76
 
<h1><a name="collation">Collation</a></h1>
77
 
<p>
78
 
  <code>ICUCollationKeyFilter</code>
79
 
  converts each token into its binary <code>CollationKey</code> using the 
80
 
  provided <code>Collator</code>, and then encode the <code>CollationKey</code>
81
 
  as a String using
82
 
  {@link org.apache.lucene.util.IndexableBinaryStringTools}, to allow it to be 
83
 
  stored as an index term.
84
 
</p>
85
 
<p>
86
 
  <code>ICUCollationKeyFilter</code> depends on ICU4J 4.4 to produce the 
87
 
  <code>CollationKey</code>s.  <code>icu4j-4.4.jar</code>
88
 
  is included in Lucene's Subversion repository at <code>contrib/icu/lib/</code>.
89
 
</p>
90
 
 
91
 
<h2>Use Cases</h2>
92
 
 
93
 
<ul>
94
 
  <li>
95
 
    Efficient sorting of terms in languages that use non-Unicode character 
96
 
    orderings.  (Lucene Sort using a Locale can be very slow.) 
97
 
  </li>
98
 
  <li>
99
 
    Efficient range queries over fields that contain terms in languages that 
100
 
    use non-Unicode character orderings.  (Range queries using a Locale can be
101
 
    very slow.)
102
 
  </li>
103
 
  <li>
104
 
    Effective Locale-specific normalization (case differences, diacritics, etc.).
105
 
    ({@link org.apache.lucene.analysis.LowerCaseFilter} and 
106
 
    {@link org.apache.lucene.analysis.ASCIIFoldingFilter} provide these services
107
 
    in a generic way that doesn't take into account locale-specific needs.)
108
 
  </li>
109
 
</ul>
110
 
 
111
 
<h2>Example Usages</h2>
112
 
 
113
 
<h3>Farsi Range Queries</h3>
114
 
<pre class="prettyprint">
115
 
  Collator collator = Collator.getInstance(new Locale("ar"));
116
 
  ICUCollationKeyAnalyzer analyzer = new ICUCollationKeyAnalyzer(collator);
117
 
  RAMDirectory ramDir = new RAMDirectory();
118
 
  IndexWriter writer = new IndexWriter
119
 
    (ramDir, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);
120
 
  Document doc = new Document();
121
 
  doc.add(new Field("content", "\u0633\u0627\u0628", 
122
 
                    Field.Store.YES, Field.Index.ANALYZED));
123
 
  writer.addDocument(doc);
124
 
  writer.close();
125
 
  IndexSearcher is = new IndexSearcher(ramDir, true);
126
 
 
127
 
  // The AnalyzingQueryParser in Lucene's contrib allows terms in range queries
128
 
  // to be passed through an analyzer - Lucene's standard QueryParser does not
129
 
  // allow this.
130
 
  AnalyzingQueryParser aqp = new AnalyzingQueryParser("content", analyzer);
131
 
  aqp.setLowercaseExpandedTerms(false);
132
 
  
133
 
  // Unicode order would include U+0633 in [ U+062F - U+0698 ], but Farsi
134
 
  // orders the U+0698 character before the U+0633 character, so the single
135
 
  // indexed Term above should NOT be returned by a ConstantScoreRangeQuery
136
 
  // with a Farsi Collator (or an Arabic one for the case when Farsi is not
137
 
  // supported).
138
 
  ScoreDoc[] result
139
 
    = is.search(aqp.parse("[ \u062F TO \u0698 ]"), null, 1000).scoreDocs;
140
 
  assertEquals("The index Term should not be included.", 0, result.length);
141
 
</pre>
142
 
 
143
 
<h3>Danish Sorting</h3>
144
 
<pre class="prettyprint">
145
 
  Analyzer analyzer 
146
 
    = new ICUCollationKeyAnalyzer(Collator.getInstance(new Locale("da", "dk")));
147
 
  RAMDirectory indexStore = new RAMDirectory();
148
 
  IndexWriter writer = new IndexWriter 
149
 
    (indexStore, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);
150
 
  String[] tracer = new String[] { "A", "B", "C", "D", "E" };
151
 
  String[] data = new String[] { "HAT", "HUT", "H\u00C5T", "H\u00D8T", "HOT" };
152
 
  String[] sortedTracerOrder = new String[] { "A", "E", "B", "D", "C" };
153
 
  for (int i = 0 ; i < data.length ; ++i) {
154
 
    Document doc = new Document();
155
 
    doc.add(new Field("tracer", tracer[i], Field.Store.YES, Field.Index.NO));
156
 
    doc.add(new Field("contents", data[i], Field.Store.NO, Field.Index.ANALYZED));
157
 
    writer.addDocument(doc);
158
 
  }
159
 
  writer.close();
160
 
  Searcher searcher = new IndexSearcher(indexStore, true);
161
 
  Sort sort = new Sort();
162
 
  sort.setSort(new SortField("contents", SortField.STRING));
163
 
  Query query = new MatchAllDocsQuery();
164
 
  ScoreDoc[] result = searcher.search(query, null, 1000, sort).scoreDocs;
165
 
  for (int i = 0 ; i < result.length ; ++i) {
166
 
    Document doc = searcher.doc(result[i].doc);
167
 
    assertEquals(sortedTracerOrder[i], doc.getValues("tracer")[0]);
168
 
  }
169
 
</pre>
170
 
 
171
 
<h3>Turkish Case Normalization</h3>
172
 
<pre class="prettyprint">
173
 
  Collator collator = Collator.getInstance(new Locale("tr", "TR"));
174
 
  collator.setStrength(Collator.PRIMARY);
175
 
  Analyzer analyzer = new ICUCollationKeyAnalyzer(collator);
176
 
  RAMDirectory ramDir = new RAMDirectory();
177
 
  IndexWriter writer = new IndexWriter
178
 
    (ramDir, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);
179
 
  Document doc = new Document();
180
 
  doc.add(new Field("contents", "DIGY", Field.Store.NO, Field.Index.ANALYZED));
181
 
  writer.addDocument(doc);
182
 
  writer.close();
183
 
  IndexSearcher is = new IndexSearcher(ramDir, true);
184
 
  QueryParser parser = new QueryParser("contents", analyzer);
185
 
  Query query = parser.parse("d\u0131gy");   // U+0131: dotless i
186
 
  ScoreDoc[] result = is.search(query, null, 1000).scoreDocs;
187
 
  assertEquals("The index Term should be included.", 1, result.length);
188
 
</pre>
189
 
 
190
 
<h2>Caveats and Comparisons</h2>
191
 
<p>
192
 
  <strong>WARNING:</strong> Make sure you use exactly the same 
193
 
  <code>Collator</code> at index and query time -- <code>CollationKey</code>s
194
 
  are only comparable when produced by
195
 
  the same <code>Collator</code>.  Since {@link java.text.RuleBasedCollator}s
196
 
  are not independently versioned, it is unsafe to search against stored
197
 
  <code>CollationKey</code>s unless the following are exactly the same (best 
198
 
  practice is to store this information with the index and check that they
199
 
  remain the same at query time):
200
 
</p>
201
 
<ol>
202
 
  <li>JVM vendor</li>
203
 
  <li>JVM version, including patch version</li>
204
 
  <li>
205
 
    The language (and country and variant, if specified) of the Locale
206
 
    used when constructing the collator via
207
 
    {@link java.text.Collator#getInstance(java.util.Locale)}.
208
 
  </li>
209
 
  <li>
210
 
    The collation strength used - see {@link java.text.Collator#setStrength(int)}
211
 
  </li>
212
 
</ol> 
213
 
<p>
214
 
  <code>ICUCollationKeyFilter</code> uses ICU4J's <code>Collator</code>, which 
215
 
  makes its version available, thus allowing collation to be versioned
216
 
  independently from the JVM.  <code>ICUCollationKeyFilter</code> is also 
217
 
  significantly faster and generates significantly shorter keys than 
218
 
  <code>CollationKeyFilter</code>.  See
219
 
  <a href="http://site.icu-project.org/charts/collation-icu4j-sun"
220
 
    >http://site.icu-project.org/charts/collation-icu4j-sun</a> for key
221
 
  generation timing and key length comparisons between ICU4J and
222
 
  <code>java.text.Collator</code> over several languages.
223
 
</p>
224
 
<p>
225
 
  <code>CollationKey</code>s generated by <code>java.text.Collator</code>s are 
226
 
  not compatible with those those generated by ICU Collators.  Specifically, if
227
 
  you use <code>CollationKeyFilter</code> to generate index terms, do not use
228
 
  <code>ICUCollationKeyFilter</code> on the query side, or vice versa.
229
 
</p>
230
 
<hr/>
231
 
<h1><a name="normalization">Normalization</a></h1>
232
 
<p>
233
 
  <code>ICUNormalizer2Filter</code> normalizes term text to a 
234
 
  <a href="http://unicode.org/reports/tr15/">Unicode Normalization Form</a>, so 
235
 
  that <a href="http://en.wikipedia.org/wiki/Unicode_equivalence">equivalent</a>
236
 
  forms are standardized to a unique form.
237
 
</p>
238
 
<h2>Use Cases</h2>
239
 
<ul>
240
 
  <li> Removing differences in width for Asian-language text. 
241
 
  </li>
242
 
  <li> Standardizing complex text with non-spacing marks so that characters are 
243
 
  ordered consistently.
244
 
  </li>
245
 
</ul>
246
 
<h2>Example Usages</h2>
247
 
<h3>Normalizing text to NFC</h3>
248
 
<pre class="prettyprint">
249
 
  /**
250
 
   * Normalizer2 objects are unmodifiable and immutable.
251
 
   */
252
 
  Normalizer2 normalizer = Normalizer2.getInstance(null, "nfc", Normalizer2.Mode.COMPOSE);
253
 
  /**
254
 
   * This filter will normalize to NFC.
255
 
   */
256
 
  TokenStream tokenstream = new ICUNormalizer2Filter(tokenizer, normalizer);
257
 
</pre>
258
 
<hr/>
259
 
<h1><a name="casefolding">Case Folding</a></h1>
260
 
<p>
261
 
Default caseless matching, or case-folding is more than just conversion to
262
 
lowercase. For example, it handles cases such as the Greek sigma, so that
263
 
"Μάϊος" and "ΜΆΪΟΣ" will match correctly.
264
 
</p>
265
 
<p>
266
 
Case-folding is still only an approximation of the language-specific rules
267
 
governing case. If the specific language is known, consider using
268
 
ICUCollationKeyFilter and indexing collation keys instead. This implementation
269
 
performs the "full" case-folding specified in the Unicode standard, and this
270
 
may change the length of the term. For example, the German ß is case-folded
271
 
to the string 'ss'.
272
 
</p>
273
 
<p>
274
 
Case folding is related to normalization, and as such is coupled with it in
275
 
this integration. To perform case-folding, you use normalization with the form
276
 
"nfkc_cf" (which is the default).
277
 
</p>
278
 
<h2>Use Cases</h2>
279
 
<ul>
280
 
  <li>
281
 
    As a more thorough replacement for LowerCaseFilter that has good behavior
282
 
    for most languages.
283
 
  </li>
284
 
</ul>
285
 
<h2>Example Usages</h2>
286
 
<h3>Lowercasing text</h3>
287
 
<pre class="prettyprint">
288
 
  /**
289
 
   * This filter will case-fold and normalize to NFKC.
290
 
   */
291
 
  TokenStream tokenstream = new ICUNormalizer2Filter(tokenizer);
292
 
</pre>
293
 
<hr/>
294
 
<h1><a name="searchfolding">Search Term Folding</a></h1>
295
 
<p>
296
 
Search term folding removes distinctions (such as accent marks) between 
297
 
similar characters. It is useful for a fuzzy or loose search.
298
 
</p>
299
 
<p>
300
 
Search term folding implements many of the foldings specified in
301
 
<a href="http://www.unicode.org/reports/tr30/tr30-4.html">Character Foldings</a>
302
 
as a special normalization form.  This folding applies NFKC, Case Folding, and
303
 
many character foldings recursively.
304
 
</p>
305
 
<h2>Use Cases</h2>
306
 
<ul>
307
 
  <li>
308
 
    As a more thorough replacement for ASCIIFoldingFilter and LowerCaseFilter 
309
 
    that applies the same ideas to many more languages. 
310
 
  </li>
311
 
</ul>
312
 
<h2>Example Usages</h2>
313
 
<h3>Removing accents</h3>
314
 
<pre class="prettyprint">
315
 
  /**
316
 
   * This filter will case-fold, remove accents and other distinctions, and
317
 
   * normalize to NFKC.
318
 
   */
319
 
  TokenStream tokenstream = new ICUFoldingFilter(tokenizer);
320
 
</pre>
321
 
<hr/>
322
 
<h1><a name="transform">Text Transformation</a></h1>
323
 
<p>
324
 
ICU provides text-transformation functionality via its Transliteration API. This allows
325
 
you to transform text in a variety of ways, taking context into account.
326
 
</p>
327
 
<p>
328
 
For more information, see the 
329
 
<a href="http://userguide.icu-project.org/transforms/general">User's Guide</a>
330
 
and 
331
 
<a href="http://userguide.icu-project.org/transforms/general/rules">Rule Tutorial</a>.
332
 
</p>
333
 
<h2>Use Cases</h2>
334
 
<ul>
335
 
  <li>
336
 
    Convert Traditional to Simplified 
337
 
  </li>
338
 
  <li>
339
 
    Transliterate between different writing systems: e.g. Romanization
340
 
  </li>
341
 
</ul>
342
 
<h2>Example Usages</h2>
343
 
<h3>Convert Traditional to Simplified</h3>
344
 
<pre class="prettyprint">
345
 
  /**
346
 
   * This filter will map Traditional Chinese to Simplified Chinese
347
 
   */
348
 
  TokenStream tokenstream = new ICUTransformFilter(tokenizer, Transliterator.getInstance("Traditional-Simplified"));
349
 
</pre>
350
 
<h3>Transliterate Serbian Cyrillic to Serbian Latin</h3>
351
 
<pre class="prettyprint">
352
 
  /**
353
 
   * This filter will map Serbian Cyrillic to Serbian Latin according to BGN rules
354
 
   */
355
 
  TokenStream tokenstream = new ICUTransformFilter(tokenizer, Transliterator.getInstance("Serbian-Latin/BGN"));
356
 
</pre>
357
 
<hr/>
358
 
<h1><a name="backcompat">Backwards Compatibility</a></h1>
359
 
<p>
360
 
This module exists to provide up-to-date Unicode functionality that supports
361
 
the most recent version of Unicode (currently 6.0). However, some users who wish 
362
 
for stronger backwards compatibility can restrict
363
 
{@link org.apache.lucene.analysis.icu.ICUNormalizer2Filter} to operate on only
364
 
a specific Unicode Version by using a {@link com.ibm.icu.text.FilteredNormalizer2}. 
365
 
</p>
366
 
<h2>Example Usages</h2>
367
 
<h3>Restricting normalization to Unicode 5.0</h3>
368
 
<pre class="prettyprint">
369
 
  /**
370
 
   * This filter will do NFC normalization, but will ignore any characters that
371
 
   * did not exist as of Unicode 5.0. Because of the normalization stability policy
372
 
   * of Unicode, this is an easy way to force normalization to a specific version.
373
 
   */
374
 
    Normalizer2 normalizer = Normalizer2.getInstance(null, "nfc", Normalizer2.Mode.COMPOSE);
375
 
    UnicodeSet set = new UnicodeSet("[:age=5.0:]");
376
 
    // see FilteredNormalizer2 docs, the set should be frozen or performance will suffer
377
 
    set.freeze(); 
378
 
    FilteredNormalizer2 unicode50 = new FilteredNormalizer2(normalizer, set);
379
 
    TokenStream tokenstream = new ICUNormalizer2Filter(tokenizer, unicode50);
380
 
</pre>
381
 
</body>
382
 
</html>