Elasticsearch Geospatial Query Geo Point

When processing search requests containing geospatial data in Elasticsearch (ES), geo_point is a core concept for building index mappings and writing documents. It allows us to store and retrieve latitude/longitude coordinates as a single field, thereby supporting various advanced query operations based on location. This article will focus on the theme of "elasticsearch-geospatial-query-geo_point" to deeply analyze how to perform precise matching, range filtering, and distance calculations for geospatial points using ES DSL.
Before writing query statements, it is crucial to ensure that the field type of the index is correctly configured as geo_point. This typically occurs during the creation of an index or when updating templates. ES automatically parses input latitude/longitude strings (such as "120.96,30.05") and converts them into a binary format used internally to optimize spatial calculation performance.

PUT /restaurants
{
  "mappings": {
    "properties": {
      "name": { "type": "text" },
      "address": { "type": "keyword" },
      "location": { "type": "geo_point", "field_name": "loc" }
    }
  }
}

At the document level, geo_point fields accept a string value. This string consists of two floating-point numbers representing longitude and latitude, separated by a comma. For example:

  • {"location": "104.395,26.78"} (Beijing)
  • {"location": "-73.9352, 40.7306"} (New York)

Understanding this basic structure is a prerequisite for performing any geospatial queries later on. If the field type is not correctly set to geo_point, ES will fail to recognize the coordinate format and return an error message or be unable to execute distance calculation logic.

Syntax for Exact Matching and Range Filtering

When looking for restaurants at specific locations, you can use a boolean query combined with term, range, and specialized geospatial filters to achieve precise control. While ES natively supports equality checks against single points, in actual business scenarios, it is more common to search based on distance or radius.

The following is an example of a typical search request aimed at finding restaurants located near Beijing with ratings higher than 4.5:

GET /restaurants/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": { "category": "fast_food" }
        },
        {
          "range": { 
            "rating": { 
              "gte": 4.5, 
              "lte": 5.0 
            } 
          }
        },
        {
          "geo_distance": {
            "location": "120.96,30.05", // Target coordinates: near Beijing center
            "distance": [ "*", "5km" ], // Radius of 5 kilometers; distance field can be customized or omitted
            "relation": "<=" 
          }
        }
      ]
    }
  },
  "_source": ["name", "address"]
}

In the example above:

  1. geo_distance is a core component. It accepts target coordinates, maximum distance (units such as km, mi), and an optional name for the distance field. If distance is not specified, ES defaults to using the _geo_distance_ field in documents to return the actual distance from the query point.
  2. The relation parameter defines comparison logic, e.g., <, >, <=, >=, or =. If this parameter is not set, it defaults to less than or equal (i.e., finding all points within the radius).

Polygon Areas and Complex Geospatial Scenarios Extension

In addition to point-to-point distance calculations, ES supports more complex geometric shape queries such as rectangles, circles, or polygons. This is very useful for defining specific administrative regions or service areas. While this article focuses on geo_point, understanding its combination with polygons can significantly enhance retrieval capabilities.

To find all restaurants located within a polygon area (assuming the region is defined by multiple points), you can use the geo_shapely query type:

GET /restaurants/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "function_score": {
            "query": {
              "match_all": {}
            },
            "functions": [
              {
                "geo_distance_factor": {
                  "location": "120.96,30.05", // Reference point
                  "distance_field": "_geo_distance"
                }
              }
            ],
            "boost_mode": "and",
            "score_mode": "sum"
          }
        },
        {
          "range": { 
            "rating": { "gte": 4.0 } 
          }
        }
      ]
    }
  }
}

In practical applications, developers often need to combine multiple query conditions based on business logic. For example, first filter out a candidate set within a certain range using geo_distance, then perform attribute filtering (such as price ranges or operating hours) via term or range, and finally use _sort to sort by distance proximity. This layered filtering strategy not only improves response speed but also ensures the accuracy of results.

Performance Optimization and Best Practice Recommendations

When handling massive amounts of geospatial data, query efficiency is critical. ES has performed extensive underlying optimizations for indexing mechanisms related to geo_point (such as building spatial inverted indexes), but users can still fine-tune via the following methods:

  • Avoid unnecessary field mappings: Ensure that only necessary coordinates are marked as geo_point, while other text descriptions remain standard string types to reduce storage overhead.
  • Reasonably set shard and replica counts: Geospatial data typically exhibits good spatial locality; appropriately reducing the number of replicas (e.g., setting it to 1) can significantly improve write and read performance.
  • Use approximate queries instead of exact calculations: If a certain error margin is acceptable in your business logic, prioritize using ES's default behavior for geo_distance rather than complex custom functions to reduce CPU consumption.

By mastering the core concepts regarding geo_point and DSL syntax outlined above, developers can build efficient and accurate geolocation search systems that meet diverse scenario requirements ranging from local life applications to logistics tracking.