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