5 OSM data is initially imported using [osm2pgsql](https://osm2pgsql.org).
6 Nominatim uses a custom flex style to create the initial import tables.
8 The import process creates the following tables:
10 
12 The `planet_osm_*` tables are the usual backing tables for OSM data. Note
13 that Nominatim uses them to look up special relations and to find nodes on
14 ways. Apart from those the osm2pgsql import produces five tables as output.
16 The **place_postcode** table collects postcode information that is not
17 already present on an object in the place table. That is for one thing
18 [postcode area relations](https://wiki.openstreetmap.org/wiki/Tag:boundary%3Dpostal_code)
19 and for another objects with a postcode tag but no other tagging that
20 qualifies it for inclusion into the geocoding database.
22 The table has the following fields:
24 * `osm_type` - kind of OSM object (**N** - node, **W** - way, **R** - relation)
25 * `osm_id` - original OSM ID
26 * `postcode` - postcode as extacted from the `postcal_code` tag
27 * `country_code` - computed country code for this postcode. This field
28 functions as a cache and is only computed when the table is used for
29 the computation of the final postcodes.
30 * `centroid` - centroid of the object
31 * `geometry` - the full geometry of the area for postcode areas only
33 The **place_interpolation** table holds all
34 [address interpolation lines](https://wiki.openstreetmap.org/wiki/Addresses#Interpolation)
35 and has the following fields:
37 * `osm_id` - original OSM ID
38 * `type` - type of interpolation as extracted from the `addr:interpolation` tag
39 * `address` - any other `addr:*` tags
40 * `nodes` - list of OSM nodes contained in this interpolation,
41 needed to compute the involved housenumbers later
42 * `geometry` - the linestring for the interpolation (in WSG84)
44 The **place** table holds all other OSM object that are interesting and
45 has the following fields:
47 * `osm_type` - kind of OSM object (**N** - node, **W** - way, **R** - relation)
48 * `osm_id` - original OSM ID
49 * `class` - key of principal tag defining the object type
50 * `type` - value of principal tag defining the object type
51 * `name` - collection of tags that contain a name or reference
52 * `admin_level` - numerical value of the tagged administrative level
53 * `address` - collection of tags defining the address of an object
54 * `extratags` - collection of additional interesting tags that are not
55 directly relevant for searching
56 * `geometry` - geometry of the object (in WGS84)
57 * `categories` - all principal tags of the object, each one as a hierarchical
58 label of the form `osm.<key>.<value>`
60 An OSM object appears at most once in this table, even when it is tagged with
61 more than one tag that may constitute a principal tag. Take for example a
62 motorway bridge. In OSM, this would be a way which is tagged with
63 `highway=motorway` and `bridge=yes`. This way gets a single row in the `place`
64 table with `categories` of `{osm.highway.motorway, osm.bridge.yes}`. The
65 *unique key* for `place` is therefore (`osm_type`, `osm_id`).
67 The `class` and `type` columns still hold a single principal tag, the one that
68 Nominatim uses to classify and rank the place. When an object has more than one
69 principal tag, then the alphabetically first key/value pair wins. Tags that are
70 only used as a fallback (see [Import styles](../customize/Import-Styles.md#main-tags))
71 contribute a category but never become `class` and `type` unless they are the
72 only principal tag of the object.
74 How raw OSM tags are mapped to the columns in the place table is to a certain
75 degree configurable. See [Customizing Import Styles](../customize/Import-Styles.md)
78 The **place_entrance** table collects the nodes that are tagged as an entrance
79 of a building or another feature. Nominatim does not make them searchable but
80 returns them together with the enclosing place. The table has the following
83 * `osm_id` - original OSM ID of the node
84 * `type` - value of the `entrance` tag
85 * `extratags` - any other tags of the entrance that may be interesting
86 * `geometry` - position of the node (in WGS84)
88 The **place_associated_street** table saves the members of
89 [associatedStreet relations](https://wiki.openstreetmap.org/wiki/Relation:associatedStreet).
90 They are used to find the street a housenumber belongs to when no `addr:street`
91 tag can be matched. The table has the following fields:
93 * `relation_id` - OSM ID of the relation
94 * `member_type`, `member_id` - reference to the OSM object that is a member
96 * `member_role` - role of the member within the relation, usually `house`
101 The following tables carry all information needed to do the search:
103 
105 The **placex** table is the central table that saves all information about the
106 searchable places in Nominatim.
108 In simpler terms, the `placex` table can be seen as the final, processed version of OSM data that is ready for search.
109 While the `place` table contains raw imported data, `placex` stores enriched and indexed data that includes ranking, hierarchy (parent-child relationships), and computed metadata such as importance and postcode.
110 Most search queries in Nominatim ultimately read from this table, making it the core table for forward and reverse geocoding.
112 The basic columns are the same as for the
113 place table and have the same meaning. The placex tables adds the following
116 * `place_id` - the internal unique ID to identify the place
117 * `partition` - the id to use with partitioned tables (see below)
118 * `geometry_sector` - a location hash used for geographically close ordering
119 * `parent_place_id` - the next higher place in the address hierarchy, only
120 relevant for POI-type places (with rank 30)
121 * `linked_place_id` - place ID of the place this object has been merged with.
122 When this ID is set, then the place is invisible for search.
123 * `importance` - measure how well known the place is
124 * `rank_search`, `rank_address` - search and address rank (see [Customizing ranking](../customize/Ranking.md)
125 * `wikipedia` - the wikipedia page used for computing the importance of the place
126 * `country_code` - the country the place is located in
127 * `housenumber` - normalized housenumber, if the place has one
128 * `postcode` - computed postcode for the place
129 * `indexed_status` - processing status of the place (0 - ready, 1 - freshly inserted, 2 - needs updating, 100 - needs deletion)
130 * `indexed_date` - timestamp when the place was processed last
131 * `centroid` - a point feature for the place
132 * `token_info` - a dummy field used to inject information from the tokenizer
133 into the indexing process
135 The `categories` column is copied from the place table. It is an array of
136 `ltree` values, so that a search for a category can use the containment
137 operator `<@` and match all descendants of a category with a single comparison.
138 The combined index `idx_placex_centroid_categories` over `centroid` and
139 `categories` backs the search for POIs of a given category around a point.
141 For implementation details, see the SQL definition in `lib-sql/tables/placex.sql` and the SQLAlchemy schema in `src/nominatim_api/sql/sqlalchemy_schema.py`.
143 The **placex_entrance** table holds the entrances that could be assigned to a
144 place, that is all entrance nodes that are part of the way of a place. The
145 columns have the same meaning as in `place_entrance` with the exception of:
147 * `place_id` - reference to the place the entrance belongs to
148 * `location` - position of the entrance node
150 The **location_property_osmline** table is a special table for
151 [address interpolations](https://wiki.openstreetmap.org/wiki/Addresses#Using_interpolation).
152 The columns have the same meaning and use as the columns with the same name in
153 the placex table. Only the following columns are special:
155 * `startnumber`, `endnumber` and `step` - beginning and end of the number range
156 for the interpolation and the increment steps
157 * `type` - a string to indicate the interval between the numbers as imported
158 from the OSM `addr:interpolation` tag; valid values are `odd`, `even`, `all`
159 or a single digit number; interpolations with other values are silently
162 Address interpolations are always ways in OSM, which is why there is no column
165 The **location_postcodes** table holds computed postcode assembled from the postcode information
166 available in OSM. When a postcode has a postcode area relation, or when the postcode geometry is
167 [imported via JSONL files](../customize/Postcodes.md#jsonl-format) then the table stores
168 its full geometry. For all other postcodes the centroid is computed using the position of all OSM
169 objects that reference the same postcode. The `osm_id` and `is_area` fields can be used to
170 distinguish the two. When `osm_id` is set, it refers to the OSM relation with the postcode area,
171 and `is_area` is `true` for postcodes with a mature geometry (either from a postcode OSM area
172 relation or imported via JSONL), `false` for postcodes without a mature geometry (guessed
173 postcode geometries). The meaning of other columns in the table is again the same as that of the
176 Every place needs an address, a set of surrounding places that describe the
177 location of the place. The set of address places is made up of OSM places
178 themselves. The **place_addressline** table cross-references for each place
179 all the places that make up its address. Two columns define the address
182 * `place_id` - reference to the place being addressed
183 * `address_place_id` - reference to the place serving as an address part
185 The most of the columns cache information from the placex entry of the address
186 part. The exceptions are:
188 * `fromarea` - is true if the address part has an area geometry and can
189 therefore be considered preceise
190 * `isaddress` - is true if the address part should show up in the address
191 output. Sometimes there are multiple places competing for for same address
192 type (e.g. multiple cities) and this field resolves the tie.
194 The **search_name** table contains the search index proper. It saves for each
195 place the terms with which the place can be found. The terms are split into
196 the name itself and all terms that make up the address. The table mirrors some
197 of the columns from placex for faster lookup.
199 Search terms are not saved as strings. Each term is assigned an integer and those
200 integers are saved in the name and address vectors of the search_name table. The
201 **word** table serves as the lookup table from string to such a word ID. The
202 exact content of the word table depends on the [tokenizer](Tokenizers.md) used.
204 ## Address computation tables
206 Next to the main search tables, there is a set of secondary helper tables used
207 to compute the address relations between places. These tables are partitioned.
208 Each country is assigned a partition number in the country_name table (see
209 below) and the data is then split between a set of tables, one for each
210 partition. Note that Nominatim still manually manages partitioned tables
211 instead of using PostgreSQL's native partitioning.
213 
215 The **search_name_X** tables are used to look up streets that appear in the
218 The **location_area_large_X** tables are used to look up larger areas
219 (administrative boundaries and place nodes) either through their geographic
220 closeness or through `addr:*` entries.
222 The **location_road_X** tables are used to find the closest street for a
225 All three table cache specific information from the placex table for their
226 selected subset of places:
228 * `keywords` and `name_vector` contain lists of term ids (from the word table)
229 that the full name of the place should match against
230 * `isguess` is true for places that are not described by an area
232 All other columns reflect their counterpart in the placex table.
234 The **location_area_country** table is not partitioned. It caches the
235 geometries of the country boundaries found in the data and is used to determine
236 the country a place is located in.
238 ## Static data tables
240 Nominatim also creates a number of static tables at import:
242 * `nominatim_properties` saves settings that must not be changed after
244 * `address_levels` save the rank information from the
245 [ranking configuration](../customize/Ranking.md)
246 * `country_name` contains a fallback of names for all countries, their
247 default languages and saves the assignment of countries to partitions.
248 * `country_osm_grid` provides a fallback for country geometries
250 ## Auxiliary data tables
252 Finally there are some table for auxiliary data:
254 * `location_property_tiger` - saves housenumber from the Tiger import. Its
255 layout is similar to that of `location_propoerty_osmline`.
256 * `import_polygon_error` - logs objects whose geometry was too broken to be
257 processed during an update
258 * `import_polygon_delete` - logs deletions of very large areas, which
259 Nominatim refuses to apply automatically, see
260 [Maintenance](../admin/Maintenance.md#removing-large-deleted-objects)