Source: https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/index/create-geo/ Documentation version: v5.3.2 # CREATE SPATIAL INDEX statement The CREATE SPATIAL INDEX statement creates a spatial index on a specific graph. To specify the graph, use either of the following methods: - Add a [USE clause](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/dql/clauses/use-graph/) before this statement to set the working graph. - Use [SESSION SET](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/sessions/set/) to set the graph for the current session in advance. If both methods are used, the one specified in the USE clause takes precedence. If neither is used, an error occurs. You can create a spatial index based on a `GEOGRAPHY` property of a node type or edge type. Spatial indexes accelerate queries of spatial range, proximity, intersection, and other spatial-related operations. To create other types of indexes, see [CREATE NORMAL INDEX](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/index/create/), [CREATE VECTOR INDEX](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/index/create-vector/), and [CREATE FULLTEXT INDEX](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/index/create-fulltext/). ## How spatial indexes are implemented In NebulaGraph Database Developer Edition, the spatial index works as follows: 1. Decompose the grid into multiple levels: The entire spatial space of the earth is projected onto a sphere and decomposed into a multi-level grid hierarchy. Each successive level further decomposes the level above it, so each upper-level cell contains a complete grid at the next level. 2. Determine the size and the number of the grid cells: The higher the level, the smaller the size of each cell, and the more cells are needed to cover the same spatial object. 3. Build the index: The system calculates the grid cells covered by a spatial object and records the mapping between spatial objects and grid cells in the index. 4. Query spatial data: The system scans only grid cells that overlap with the target spatial object, quickly locating the target spatial objects. The following figure shows an example where a space is decomposed into a 4-level `4x4` grid, resulting in a total of `65,536` cells on the 4th level.. [![geo index](https://docs-cdn.nebula-graph.com.cn/figures/5.0/spatial_index_20250716.png)](https://docs-cdn.nebula-graph.com.cn/figures/5.0/spatial_index_20250716.png) You can refer to the `level` (the grid level) and `average area` (the size of each cell) column in [S2 Cell Statistics](https://s2geometry.io/resources/s2cell_statistics.html), and configure the parameter [`s2_max_level`](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/index/create-geo/#s2_max_level) and [`s2_max_cells`](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/index/create-geo/#s2_max_cells) to optimize the index for your specific use case. Note An operation involving a non-default schema or an object in it requires access to the schema, either implicitly or through an explicit `USAGE` grant, as well as the privilege required for the operation. The schema access check and the privilege check for the requested operation are independent; satisfying one does not satisfy the other. Schema access control does not apply to temporary graphs or built-in procedures and functions. For more information, see [Schema access control](https://dev-docs.nebula-graph.io/v5.3.2/server-admin/authorization/schema-access-control/). ## Prerequisites - A graph is created. For more information, see [CREATE GRAPH](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/graph/create/). - To create a spatial index, you must either be the owner of the graph, be granted to perform the action `INDEX` on the graph, or be granted to perform the action `CREATE INDEX` on the used schema. For more information, see [Roles and privileges](https://dev-docs.nebula-graph.io/v5.3.2/server-admin/authorization/). ## Syntax diagramsource create_spatial_index_statement spatial_index_configuration ```` create_spatial_index_statement ::= 'CREATE' 'SPATIAL' 'INDEX' ('IF NOT EXISTS')? index_name 'ON' ( ( ('NODE' | 'VERTEX') 'TYPE'? node_type_name) | ( ('EDGE'|'RELATIONSHIP') 'TYPE'? edge_type_name) ) '(' spatial_index_configuration ')' spatial_index_configuration ::= 'geography_property_name' ',' 's2_max_level' '=' int_value ',' 's2_max_cells' '=' int_value ```` ## Parameters ### `IF NOT EXISTS` This clause checks if an index with the same name already exists. If it already exists, the index is not created and no exception is thrown. If you do not specify this clause, an exception is thrown if an index with the same name already exists. ### `index_name` The name of the spatial index to be created. The name is a regular identifier, and must be unique among all types of indexes within the same graph. For more information, see [Rules for naming identifiers](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/overview/keywords-identifiers/#rules_for_naming_identifiers). ### `node_type_name` The name of the node type on which the spatial index is created. The node type must have at least one property of type `GEOGRAPHY`. ### `edge_type_name` The name of the edge type on which the spatial index is created. The edge type must have at least one property of type `GEOGRAPHY`. ### `spatial_index_configuration` The property based on which the spatial index is created and its index configurations. Only one property can be indexed per spatial index. #### `geography_property_name` The name of the property to be indexed. The property must be of type `GEOGRAPHY`. #### `s2_max_level` The maximum level of the grid that can be decomposed. Higher levels create finer grids with smaller cells, increasing index size and maintenance costs. Valid range: `(0, 30]`. #### `s2_max_cells` The maximum number of cells a spatial object can be covered. Lower values reduce index records, storage, and query complexity but may decrease index precision. Valid range: `(0, 256]`. ## Examples The following examples are based on the graph `my_graph` created in [How to use spatial data](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/data-types/geo-type/#how_to_use). ### Create a spatial index on a node type ```` USE my_graph CREATE SPATIAL INDEX IF NOT EXISTS idx_gnode_g ON NODE Person(any_geo, s2_max_level = 30, s2_max_cells = 8) ```` The preceding example creates a spatial index named `idx_gnode_g` on the node type `Person` for the property `any_geo`, with a maximum grid level of `30` and up to `8` covering cells. ### Create a spatial index on an edge type ```` USE my_graph CREATE SPATIAL INDEX IF NOT EXISTS idx_gedge_g ON EDGE GEdge(company_location, s2_max_level = 30, s2_max_cells = 8) ```` The preceding example creates a spatial index named `idx_gedge_g` on the edge type `GEdge` for the property `company_location`, with a maximum grid level of `30` and up to `8` covering cells.