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.
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.
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
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 currently the default.
24 To enable the tokenizer add the following line to your project configuration:
27 NOMINATIM_TOKENIZER=legacy
30 The Postgresql module for the tokenizer is available in the `module` directory
31 and also installed with the remainder of the software under
32 `lib/nominatim/module/nominatim.so`. You can specify a custom location for
36 NOMINATIM_DATABASE_MODULE_PATH=<path to directory where nominatim.so resides>
39 This is in particular useful when the database runs on a different server.
40 See [Advanced installations](Advanced-Installations.md#importing-nominatim-to-an-external-postgresql-database) for details.
42 There are no other configuration options for the legacy tokenizer. All
43 normalization functions are hard-coded.
48 This tokenizer is currently in active development and still subject
49 to backwards-incompatible changes.
51 The ICU tokenizer uses the [ICU library](http://site.icu-project.org/) to
52 normalize names and queries. It also offers configurable decomposition and
53 abbreviation handling.
57 On import the tokenizer processes names in the following four stages:
59 1. The **Normalization** part removes all non-relevant information from the
61 2. Incoming names are now converted to **full names**. This process is currently
62 hard coded and mostly serves to handle name tags from OSM that contain
63 multiple names (e.g. [Biel/Bienne](https://www.openstreetmap.org/node/240097197)).
64 3. Next the tokenizer creates **variants** from the full names. These variants
65 cover decomposition and abbreviation handling. Variants are saved to the
66 database, so that it is not necessary to create the variants for a search
68 4. The final **Tokenization** step converts the names to a simple ASCII form,
69 potentially removing further spelling variants for better matching.
71 At query time only stage 1) and 4) are used. The query is normalized and
72 tokenized and the resulting string used for searching in the database.
76 The ICU tokenizer is configured using a YAML file which can be configured using
77 `NOMINATIM_TOKENIZER_CONFIG`. The configuration is read on import and then
78 saved as part of the internal database status. Later changes to the variable
81 Here is an example configuration file:
86 - "ß > 'ss'" # German szet is unimbigiously equal to double ss
88 - !include /etc/nominatim/icu-rules/extended-unicode-to-asccii.yaml
98 - bridge -> bdge,br,brdg,bri,brg
101 The configuration file contains three sections:
102 `normalization`, `transliteration`, `variants`.
104 The normalization and transliteration sections each must contain a list of
105 [ICU transformation rules](https://unicode-org.github.io/icu/userguide/transforms/general/rules.html).
106 The rules are applied in the order in which they appear in the file.
107 You can also include additional rules from external yaml file using the
108 `!include` tag. The included file must contain a valid YAML list of ICU rules
109 and may again include other files.
112 The ICU rule syntax contains special characters that conflict with the
113 YAML syntax. You should therefore always enclose the ICU rules in
116 The variants section defines lists of replacements which create alternative
117 spellings of a name. To create the variants, a name is scanned from left to
118 right and the longest matching replacement is applied until the end of the
121 The variants section must contain a list of replacement groups. Each group
122 defines a set of properties that describes where the replacements are
123 applicable. In addition, the word section defines the list of replacements
124 to be made. The basic replacement description is of the form:
127 <source>[,<source>[...]] => <target>[,<target>[...]]
130 The left side contains one or more `source` terms to be replaced. The right side
131 lists one or more replacements. Each source is replaced with each replacement
135 The source and target terms are internally normalized using the
136 normalization rules given in the configuration. This ensures that the
137 strings match as expected. In fact, it is better to use unnormalized
138 words in the configuration because then it is possible to change the
139 rules for normalization later without having to adapt the variant rules.
143 In its standard form, only full words match against the source. There
144 is a special notation to match the prefix and suffix of a word:
147 - ~strasse => str # matches "strasse" as full word and in suffix position
148 - hinter~ => hntr # matches "hinter" as full word and in prefix position
151 There is no facility to match a string in the middle of the word. The suffix
152 and prefix notation automatically trigger the decomposition mode: two variants
153 are created for each replacement, one with the replacement attached to the word
154 and one separate. So in above example, the tokenization of "hauptstrasse" will
155 create the variants "hauptstr" and "haupt str". Similarly, the name "rote strasse"
156 triggers the variants "rote str" and "rotestr". By having decomposition work
157 both ways, it is sufficient to create the variants at index time. The variant
158 rules are not applied at query time.
160 To avoid automatic decomposition, use the '|' notation:
166 simply changes "hauptstrasse" to "hauptstr" and "rote strasse" to "rote str".
168 #### Initial and final terms
170 It is also possible to restrict replacements to the beginning and end of a
174 - ^south => s # matches only at the beginning of the name
175 - road$ => rd # matches only at the end of the name
178 So the first example would trigger a replacement for "south 45th street" but
179 not for "the south beach restaurant".
181 #### Replacements vs. variants
183 The replacement syntax `source => target` works as a pure replacement. It changes
184 the name instead of creating a variant. To create an additional version, you'd
185 have to write `source => source,target`. As this is a frequent case, there is
186 a shortcut notation for it:
189 <source>[,<source>[...]] -> <target>[,<target>[...]]
192 The simple arrow causes an additional variant to be added. Note that
193 decomposition has an effect here on the source as well. So a rule
199 means that for a word like `hauptstrasse` four variants are created:
200 `hauptstrasse`, `haupt strasse`, `hauptstr` and `haupt str`.
204 Changing the configuration after the import is currently not possible, although
205 this feature may be added at a later time.