]> git.openstreetmap.org Git - nominatim.git/blob - docs/customize/Tokenizers.md
3c29972d7eedbf93a43e6946985281a737749fd2
[nominatim.git] / docs / customize / Tokenizers.md
1 # Tokenizers
2
3 The tokenizer module in Nominatim is responsible for analysing the names given
4 to OSM objects and the terms of an incoming query in order to make sure, they
5 can be matched appropriately.
6
7 Nominatim currently offers only one tokenizer module, the ICU tokenizer. This section
8 describes the tokenizer and how it can be configured.
9
10 !!! important
11     The selection of tokenizer is tied to a database installation. You need to choose
12     and configure the tokenizer before starting the initial import. Once the import
13     is done, you cannot switch to another tokenizer anymore. Reconfiguring the
14     chosen tokenizer is very limited as well. See the comments in each tokenizer
15     section.
16
17 ## ICU tokenizer
18
19 The ICU tokenizer uses the [ICU library](http://site.icu-project.org/) to
20 normalize names and queries. It also offers configurable decomposition and
21 abbreviation handling.
22 This tokenizer is currently the default.
23
24 To enable the tokenizer add the following line to your project configuration:
25
26 ```
27 NOMINATIM_TOKENIZER=icu
28 ```
29
30 ### How it works
31
32 On import the tokenizer processes names in the following three stages:
33
34 1. During the **Sanitizer step** incoming names are cleaned up and converted to
35    **full names**. This step can be used to regularize spelling, split multi-name
36    tags into their parts and tag names with additional attributes. See the
37    [Sanitizers section](#sanitizers) below for available cleaning routines.
38 2. The **Normalization** part removes all information from the full names
39    that are not relevant for search.
40 3. The **Token analysis** step takes the normalized full names and creates
41    all transliterated variants under which the name should be searchable.
42    See the [Token analysis](#token-analysis) section below for more
43    information.
44
45 During query time, the tokeinzer is responsible for processing incoming
46 queries. This happens in two stages:
47
48 1. During **query preprocessing** the incoming text is split into name
49    chunks and normalised. This usually means applying the same normalisation
50    as during the import process but may involve other processing like,
51    for example, word break detection.
52 2. The **token analysis** step breaks down the query parts into tokens,
53    looks them up in the database and assignes them possible functions and
54    probabilities.
55
56 Query processing can be further customized while the rest of the analysis
57 is hard-coded.
58
59 ### Configuration
60
61 The ICU tokenizer is configured using a YAML file which can be configured using
62 `NOMINATIM_TOKENIZER_CONFIG`. The configuration is read on import and then
63 saved as part of the internal database status. Later changes to the variable
64 have no effect.
65
66 Here is an example configuration file:
67
68 ``` yaml
69 query-preprocessing:
70     - normalize
71 normalization:
72     - ":: lower ()"
73     - "ß > 'ss'" # German szet is unambiguously equal to double ss
74 transliteration:
75     - !include /etc/nominatim/icu-rules/extended-unicode-to-asccii.yaml
76     - ":: Ascii ()"
77 sanitizers:
78     - step: split-name-list
79 token-analysis:
80     - analyzer: generic
81       variants:
82           - !include icu-rules/variants-ca.yaml
83           - words:
84               - road -> rd
85               - bridge -> bdge,br,brdg,bri,brg
86       mutations:
87           - pattern: 'ä'
88             replacements: ['ä', 'ae']
89 ```
90
91 The configuration file contains four sections:
92 `normalization`, `transliteration`, `sanitizers` and `token-analysis`.
93
94 #### Query preprocessing
95
96 The section for `query-preprocessing` defines an ordered list of functions
97 that are applied to the query before the token analysis.
98
99 The following is a list of preprocessors that are shipped with Nominatim.
100
101 ##### normalize
102
103 ::: nominatim_api.query_preprocessing.normalize
104     options:
105         members: False
106         heading_level: 6
107         docstring_section_style: spacy
108
109
110 #### Normalization and Transliteration
111
112 The normalization and transliteration sections each define a set of
113 ICU rules that are applied to the names.
114
115 The **normalization** rules are applied after sanitation. They should remove
116 any information that is not relevant for search at all. Usual rules to be
117 applied here are: lower-casing, removing of special characters, cleanup of
118 spaces.
119
120 The **transliteration** rules are applied at the end of the tokenization
121 process to transfer the name into an ASCII representation. Transliteration can
122 be useful to allow for further fuzzy matching, especially between different
123 scripts.
124
125 Each section must contain a list of
126 [ICU transformation rules](https://unicode-org.github.io/icu/userguide/transforms/general/rules.html).
127 The rules are applied in the order in which they appear in the file.
128 You can also include additional rules from external yaml file using the
129 `!include` tag. The included file must contain a valid YAML list of ICU rules
130 and may again include other files.
131
132 !!! warning
133     The ICU rule syntax contains special characters that conflict with the
134     YAML syntax. You should therefore always enclose the ICU rules in
135     double-quotes.
136
137 #### Sanitizers
138
139 The sanitizers section defines an ordered list of functions that are applied
140 to the name and address tags before they are further processed by the tokenizer.
141 They allows to clean up the tagging and bring it to a standardized form more
142 suitable for building the search index.
143
144 !!! hint
145     Sanitizers only have an effect on how the search index is built. They
146     do not change the information about each place that is saved in the
147     database. In particular, they have no influence on how the results are
148     displayed. The returned results always show the original information as
149     stored in the OpenStreetMap database.
150
151 Each entry contains information of a sanitizer to be applied. It has a
152 mandatory parameter `step` which gives the name of the sanitizer. Depending
153 on the type, it may have additional parameters to configure its operation.
154
155 The order of the list matters. The sanitizers are applied exactly in the order
156 that is configured. Each sanitizer works on the results of the previous one.
157
158 The following is a list of sanitizers that are shipped with Nominatim.
159
160 ##### split-name-list
161
162 ::: nominatim_db.tokenizer.sanitizers.split_name_list
163     options:
164         members: False
165         heading_level: 6
166         docstring_section_style: spacy
167
168 ##### strip-brace-terms
169
170 ::: nominatim_db.tokenizer.sanitizers.strip_brace_terms
171     options:
172         members: False
173         heading_level: 6
174         docstring_section_style: spacy
175
176 ##### tag-analyzer-by-language
177
178 ::: nominatim_db.tokenizer.sanitizers.tag_analyzer_by_language
179     options:
180         members: False
181         heading_level: 6
182         docstring_section_style: spacy
183
184 ##### clean-housenumbers
185
186 ::: nominatim_db.tokenizer.sanitizers.clean_housenumbers
187     options:
188         members: False
189         heading_level: 6
190         docstring_section_style: spacy
191
192 ##### clean-postcodes
193
194 ::: nominatim_db.tokenizer.sanitizers.clean_postcodes
195     options:
196         members: False
197         heading_level: 6
198         docstring_section_style: spacy
199
200 ##### clean-tiger-tags
201
202 ::: nominatim_db.tokenizer.sanitizers.clean_tiger_tags
203     options:
204         members: False
205         heading_level: 6
206         docstring_section_style: spacy
207
208 #### delete-tags
209
210 ::: nominatim_db.tokenizer.sanitizers.delete_tags
211     options:
212         members: False
213         heading_level: 6
214         docstring_section_style: spacy
215
216 #### tag-japanese
217
218 ::: nominatim_db.tokenizer.sanitizers.tag_japanese
219     options:
220         members: False
221         heading_level: 6
222         docstring_section_style: spacy
223
224 #### Token Analysis
225
226 Token analyzers take a full name and transform it into one or more normalized
227 form that are then saved in the search index. In its simplest form, the
228 analyzer only applies the transliteration rules. More complex analyzers
229 create additional spelling variants of a name. This is useful to handle
230 decomposition and abbreviation.
231
232 The ICU tokenizer may use different analyzers for different names. To select
233 the analyzer to be used, the name must be tagged with the `analyzer` attribute
234 by a sanitizer (see for example the
235 [tag-analyzer-by-language sanitizer](#tag-analyzer-by-language)).
236
237 The token-analysis section contains the list of configured analyzers. Each
238 analyzer must have an `id` parameter that uniquely identifies the analyzer.
239 The only exception is the default analyzer that is used when no special
240 analyzer was selected. There are analysers with special ids:
241
242  * '@housenumber'. If an analyzer with that name is present, it is used
243    for normalization of house numbers.
244  * '@potcode'. If an analyzer with that name is present, it is used
245    for normalization of postcodes.
246
247 Different analyzer implementations may exist. To select the implementation,
248 the `analyzer` parameter must be set. The different implementations are
249 described in the following.
250
251 ##### Generic token analyzer
252
253 The generic analyzer `generic` is able to create variants from a list of given
254 abbreviation and decomposition replacements and introduce spelling variations.
255
256 ###### Variants
257
258 The optional 'variants' section defines lists of replacements which create alternative
259 spellings of a name. To create the variants, a name is scanned from left to
260 right and the longest matching replacement is applied until the end of the
261 string is reached.
262
263 The variants section must contain a list of replacement groups. Each group
264 defines a set of properties that describes where the replacements are
265 applicable. In addition, the word section defines the list of replacements
266 to be made. The basic replacement description is of the form:
267
268 ```
269 <source>[,<source>[...]] => <target>[,<target>[...]]
270 ```
271
272 The left side contains one or more `source` terms to be replaced. The right side
273 lists one or more replacements. Each source is replaced with each replacement
274 term.
275
276 !!! tip
277     The source and target terms are internally normalized using the
278     normalization rules given in the configuration. This ensures that the
279     strings match as expected. In fact, it is better to use unnormalized
280     words in the configuration because then it is possible to change the
281     rules for normalization later without having to adapt the variant rules.
282
283 ###### Decomposition
284
285 In its standard form, only full words match against the source. There
286 is a special notation to match the prefix and suffix of a word:
287
288 ``` yaml
289 - ~strasse => str  # matches "strasse" as full word and in suffix position
290 - hinter~ => hntr  # matches "hinter" as full word and in prefix position
291 ```
292
293 There is no facility to match a string in the middle of the word. The suffix
294 and prefix notation automatically trigger the decomposition mode: two variants
295 are created for each replacement, one with the replacement attached to the word
296 and one separate. So in above example, the tokenization of "hauptstrasse" will
297 create the variants "hauptstr" and "haupt str". Similarly, the name "rote strasse"
298 triggers the variants "rote str" and "rotestr". By having decomposition work
299 both ways, it is sufficient to create the variants at index time. The variant
300 rules are not applied at query time.
301
302 To avoid automatic decomposition, use the '|' notation:
303
304 ``` yaml
305 - ~strasse |=> str
306 ```
307
308 simply changes "hauptstrasse" to "hauptstr" and "rote strasse" to "rote str".
309
310 ###### Initial and final terms
311
312 It is also possible to restrict replacements to the beginning and end of a
313 name:
314
315 ``` yaml
316 - ^south => s  # matches only at the beginning of the name
317 - road$ => rd  # matches only at the end of the name
318 ```
319
320 So the first example would trigger a replacement for "south 45th street" but
321 not for "the south beach restaurant".
322
323 ###### Replacements vs. variants
324
325 The replacement syntax `source => target` works as a pure replacement. It changes
326 the name instead of creating a variant. To create an additional version, you'd
327 have to write `source => source,target`. As this is a frequent case, there is
328 a shortcut notation for it:
329
330 ```
331 <source>[,<source>[...]] -> <target>[,<target>[...]]
332 ```
333
334 The simple arrow causes an additional variant to be added. Note that
335 decomposition has an effect here on the source as well. So a rule
336
337 ``` yaml
338 - "~strasse -> str"
339 ```
340
341 means that for a word like `hauptstrasse` four variants are created:
342 `hauptstrasse`, `haupt strasse`, `hauptstr` and `haupt str`.
343
344 ###### Mutations
345
346 The 'mutation' section in the configuration describes an additional set of
347 replacements to be applied after the variants have been computed.
348
349 Each mutation is described by two parameters: `pattern` and `replacements`.
350 The pattern must contain a single regular expression to search for in the
351 variant name. The regular expressions need to follow the syntax for
352 [Python regular expressions](file:///usr/share/doc/python3-doc/html/library/re.html#regular-expression-syntax).
353 Capturing groups are not permitted.
354 `replacements` must contain a list of strings that the pattern
355 should be replaced with. Each occurrence of the pattern is replaced with
356 all given replacements. Be mindful of combinatorial explosion of variants.
357
358 ###### Modes
359
360 The generic analyser supports a special mode `variant-only`. When configured
361 then it consumes the input token and emits only variants (if any exist). Enable
362 the mode by adding:
363
364 ```
365   mode: variant-only
366 ```
367
368 to the analyser configuration.
369
370 ##### Housenumber token analyzer
371
372 The analyzer `housenumbers` is purpose-made to analyze house numbers. It
373 creates variants with optional spaces between numbers and letters. Thus,
374 house numbers of the form '3 a', '3A', '3-A' etc. are all considered equivalent.
375
376 The analyzer cannot be customized.
377
378 ##### Postcode token analyzer
379
380 The analyzer `postcodes` is pupose-made to analyze postcodes. It supports
381 a 'lookup' variant of the token, which produces variants with optional
382 spaces. Use together with the clean-postcodes sanitizer.
383
384 The analyzer cannot be customized.
385
386 ### Reconfiguration
387
388 Changing the configuration after the import is currently not possible, although
389 this feature may be added at a later time.