]> git.openstreetmap.org Git - nominatim.git/blob - docs/develop/Indexing.md
Merge pull request #2963 from lonvia/add-sqlalchemy-schema
[nominatim.git] / docs / develop / Indexing.md
1 # Indexing Places
2
3 In Nominatim, the word __indexing__ refers to the process that takes the raw
4 OpenStreetMap data from the place table, enriches it with address information
5 and creates the search indexes. This section explains the basic data flow.
6
7
8 ## Initial import
9
10 After osm2pgsql has loaded the raw OSM data into the place table,
11 the data is copied to the final search tables placex and location_property_osmline.
12 While they are copied, some basic properties are added:
13
14  * country_code, geometry_sector and partition
15  * initial search and address rank
16
17 In addition the column `indexed_status` is set to `1` marking the place as one
18 that needs to be indexed.
19
20 All this happens in the triggers `placex_insert` and `osmline_insert`.
21
22 ## Indexing
23
24 The main work horse of the data import is the indexing step, where Nominatim
25 takes every place from the placex and location_property_osmline tables where
26 the indexed_status != 0 and computes the search terms and the address parts
27 of the place.
28
29 The indexing happens in three major steps:
30
31 1. **Data preparation** - The indexer gets the data for the place to be indexed
32    from the database.
33
34 2. **Search name processing** - The prepared data is given to the
35    tokenizer which computes the search terms from the names
36    and potentially other information.
37
38 3. **Address processing** - The indexer then hands the prepared data and the
39    tokenizer information back to the database via an `INSERT` statement which
40    also sets the indexed_status to `0`. This triggers the update triggers
41    `placex_update`/`osmline_update` which do the work of computing address
42    parts and filling all the search tables.
43
44 When computing the address terms of a place, Nominatim relies on the processed
45 search names of all the address parts. That is why places are processed in rank
46 order, from smallest rank to largest. To ensure correct handling of linked
47 place nodes, administrative boundaries are processed before all other places.
48
49 Apart from these restrictions, each place can be indexed independently
50 from the others. This allows a large degree of parallelization during the indexing.
51 It also means that the indexing process can be interrupted at any time and
52 will simply pick up where it left of when restarted.
53
54 ### Data preparation
55
56 The data preparation step computes and retrieves all data for a place that
57 might be needed for the next step of processing the search name. That includes
58
59 * location information (country code)
60 * place classification (class, type, ranks)
61 * names (including names of linked places)
62 * address information (`addr:*` tags)
63
64 Data preparation is implemented in pl/PgSQL mostly in the functions
65 `placex_indexing_prepare()` and `get_interpolation_address()`.
66
67 #### `addr:*` tag inheritance
68
69 Nominatim has limited support for inheriting address tags from a building
70 to POIs inside the building. This only works when the address tags are on the
71 building outline. Any rank 30 object inside such a building or on its outline
72 inherits all address tags when it does not have any address tags of its own.
73
74 The inheritance is computed in the data preparation step.
75
76 ### Search name processing
77
78 The prepared place information is handed to the tokenizer next. This is a
79 Python module responsible for processing the names  from both name and address
80 terms and building up the word index from them. The process is explained in
81 more detail in the [Tokenizer chapter](Tokenizers.md).
82
83 ### Address processing
84
85 Finally, the preprocessed place information and the results of the search name
86 processing are written back to the database. At this point the update trigger
87 of the placex/location_property_osmline tables take over and fill all the
88 dependent tables. This makes up the most work-intensive part of the indexing.
89
90 Nominatim distinguishes between dependent and independent places.
91 **Dependent places** are all places on rank 30: house numbers, POIs etc. These
92 places don't have a full address of their own. Instead they are attached to
93 a parent street or place and use the information of the parent for searching
94 and displaying information. Everything else are **independent places**: streets,
95 parks, water bodies, suburbs, cities, states etc.  They receive a full address
96 on their own.
97
98 The address processing for both types of places is very different.
99
100 #### Independent places
101
102 To compute the address of an independent place Nominatim searches for all
103 places that cover the place to compute the address for at least partially.
104 For places with an area, that area is used to check for coverage. For place
105 nodes an artificial square area is computed according to the rank of
106 the place. The lower the rank the lager the area. The `location_area_large_X`
107 tables are there to facilitate the lookup. All places that can function as
108 the address of another place are saved in those tables.
109
110 `addr:*` and `isin:*` tags are taken into account to compute the address, too.
111 Nominatim will give preference to places with the same name as in these tags
112 when looking for places in the vicinity. If there are no matching place names
113 at all, then the tags are at least added to the search index. That means that
114 the names will not be shown in the result as the 'address' of the place, but
115 searching by them still works.
116
117 Independent places are always added to the global search index `search_name`.
118
119 #### Dependent places
120
121 Dependent places skip the full address computation for performance reasons.
122 Instead they just find a parent place to attach themselves to.
123
124 ![parenting of dependent places](parenting-flow.svg)
125
126 By default a POI
127 or house number will be attached to the closest street. That can be any major
128 or minor street indexed by Nominatim. In the default configuration that means
129 that it can attach itself to a footway but only when it has a name.
130
131 When the dependent place has an `addr:street` tag, then Nominatim will first
132 try to find a street with the same name before falling back to the closest
133 street.
134
135 There are also addresses in OSM, where the housenumber does not belong
136 to a street at all. These have an `addr:place` tag. For these places, Nominatim
137 tries to find a place with the given name in the indexed places with an
138 address rank between 16 and 25. If none is found, then the dependent place
139 is attached to the closest place in that category and the addr:place name is
140 added as *unlisted* place, which indicates to Nominatim that it needs to add
141 it to the address output, no matter what. This special case is necessary to
142 cover addresses that don't really refer to an existing object.
143
144 When an address has both the `addr:street` and `addr:place` tag, then Nominatim
145 assumes that the `addr:place` tag in fact should be the city part of the address
146 and give the POI the usual street number address.
147
148 Dependent places are only added to the global search index `search_name` when
149 they have either a name themselves or when they have address tags that are not
150 covered by the places that make up their address. The latter ensures that
151 addresses are always searchable by those address tags.
152