Geospatial Queries

    +
    Geospatial queries return documents that contain location-data.

    Introduction to Geospatial Querying

    A geospatial query specifies an area, and returns each document that contains a reference to a location within the area. Areas and locations are represented by means of latitude-longitude coordinate pairs.

    A geospatial query can specify an area by means of:

    • A location, expressed as a latitude-longitude coordinate pair; and a distance. The location determines the center of a circle whose radius-length is the specified distance. Documents are returned if they reference a location within the area of the circle. See Specifying Distances, below, for details of the units and formats in which distances can be specified.

    • Two latitude-longitude coordinate pairs. These are respectively taken to indicate the top left and bottom right corners of a rectangle. Documents are returned if they reference a location within the area of the rectangle.

    • An array of three or more latitude-longitude coordinate pairs. Each of the pairs is taken to indicate one corner of a polygon. Documents are returned if they reference a location within the area of the polygon.

    To be successful, a geospatial query must reference an index within which the geopoint type mapping has been applied to the field containing the target latitude-longitude coordinate pair.

    Geospatial queries return all documents whose locations are within the query-specified area. To specify holes within the area, so that one or more subsets of returned documents can be omitted from the final results, boolean queries should be applied to the set of documents returned by the geospatial query. See Query Types.

    Latitude-longitude coordinate pairs can be specified in multiple ways, including as geohashes; as demonstrated in Specifying Coordinates, below.

    Recognizing Target Data

    The travel-sample bucket, provided for test and development, contains multiple documents that specify locations. For example, those that represent airports, such as airport_1254:

    {
      "airportname": "Calais Dunkerque",
      "city": "Calais",
      "country": "France",
      "faa": "CQF",
      "geo": {
        "alt": 12,
        "lat": 50.962097,
        "lon": 1.954764
      },
      "icao": "LFAC",
      "id": 1254,
      "type": "airport",
      "tz": "Europe/Paris"
    }

    The geo field contains the lon and lat key-value pairs. Such a parent-field is accessed directly by a geospatial query: the internal long and lat child-fields are not explicitly specified. Moreover, any other child-field, such as alt, is ignored.

    For information on installing the travel-sample bucket, see Sample Buckets.

    Specifying Coordinates

    Each latitude-longitude coordinate can be expressed by means of any of the following.

    Two Key-Value Pairs

    An individual latitude-longitude coordinate can be expressed by means of an object containing two key-value pairs. For example, the central location for a radius-based area can be expressed as follows:

    "location": {
           "lon": -2.235143,
           "lat": 53.482358
         }

    Where multiple coordinates are required, for the specifying of a polygon, an array of such objects can be specified, as follows:

    "polygon_points": [
      { “lat”: 37.79393211306212, “lon”: -122.44234633404847 },
      { “lat”: 37.77995881733997, “lon”: -122.43977141339417 },
      { “lat”: 37.788031092020155, “lon”: -122.4292571540557 },
      { “lat”: 37.79026946582319, “lon”: -122.41149020154114 },
      { “lat”: 37.79571192027403, “lon”: -122.40735054016113 },
      { “lat”: 37.79393211306212, “lon”: -122.44234633404847 }
    ]

    A String, Containing Two Floating-Point Numbers

    An individual latitude-longitude coordinate can be expressed as a string, containing two floating-point numbers — the first signifying latitude, the second longitude. For example, the center of a circle can be specified as follows:

    "location": "53.482358,-2.235143"

    Where multiple coordinates are required, for the specifying of a polygon, an array of such strings can be specified, as follows:

    "polygon_points": [
      "37.79393211306212,-122.44234633404847",
      "37.77995881733997,-122.43977141339417",
      "37.788031092020155,-122.42925715405579",
      "37.79026946582319,-122.41149020154114",
      "37.79571192027403,-122.40735054016113",
      "37.79393211306212,-122.44234633404847"
    ]

    An Array of Two Floating-Point Numbers

    An individual latitude-longitude coordinate can be expressed as an array of two floating-point numbers — the first signifying longitude, the second latitude. For example, the top left corner of a rectangle can be specified as follows:

    "top_left": [ -2.235143, 53.482358 ]

    Where multiple coordinates are required, for the specifying of a polygon, an array of such arrays can be specified, as follows:

    "polygon_points": [
      [ -122.44234633404847, 37.79393211306212 ],
      [ -122.43977141339417, 37.77995881733997 ],
      [ -122.42925715405579, 37.78803109202015 ],
      [ -122.41149020154114, 37.79026946582319 ],
      [ -122.40735054016113, 37.79571192027403 ],
      [ -122.44234633404847, 37.79393211306212 ]
    ]

    A Geohash

    A latitude-longitude coordinate can be expressed by means of a single Geohash encoding. For example, the bottom right corner of a rectangle can be specified as follows:

    "bottom_right": "gcw2m0hmm6hs"

    Where multiple coordinates are required, for the specifying of a polygon, an array of geohashes can be specified, as follows:

    "polygon_points": [
      “9q8zjbkp”,
      “9q8yvvdh”,
      “9q8yyp1e”,
      “9q8yyrw8”,
      “9q8zn83x”,
      “9q8zjb0j”
    ]

    Means of latitude-longitude conversion to and from this format are provided at Geohash Converter. Additional information, including on the precision of values specified in this format, is provided at Movable Type Scripts — Geohashes.

    Specifying Distance

    Multiple unit-types can be used to express distance. These are listed in the table below, with the strings that specify them in REST queries.

    Units Specify with

    inches

    in or inch

    feet

    ft or feet

    yards

    yd or yards

    miles

    mi or miles

    nautical miles

    nm or nauticalmiles

    millimeters

    mm or millimeters

    centimeters

    cm or centimeters

    meters

    m or meters

    kilometers

    km or kilometers

    The integer used to specify the number of units must precede the unit-name, with no space left in-between. For example, five inches can be specified either by the string "5in", or by the string "5inches"; while thirteen nautical miles can be specified as either "13nm" or "13nauticalmiles".

    If the unit cannot be determined, the entire string is parsed, and the distance is assumed to be in meters.

    Creating a Geospatial Index

    To be successful, a geospatial query must reference an index that applies the geopoint type mapping to the field containing the latitude-longitude coordinate pair. This can be achieved with Couchbase Web Console, or with the REST endpoints provided for managing Indexes. Detailed instructions for setting up indexes, and specifying type mappings, are provided in Creating Indexes. For initial experimentation with geospatial querying, the geo field of documents within the travel-sample bucket can be specified as a child field of the default type mapping, as follows:

    fts geopoint definition

    The index so created can also be specified by means of the Couchbase REST API. See Demonstration Indexes for the body of the index to be used, and see Index-Creation with the REST API for information on using the REST syntax.

    Creating a Query: Radius-Based

    This section and those following provide examples of the query-bodies required to make geospatial queries with the Couchbase REST API. Note that more detailed information on performing queries with the Couchbase REST API can be found in Searching with the REST API; which shows how to use the full curl command, and how to incorporate query-bodies into it.

    The following query-body specifies a longitude of -2.235143, and a latitude of 53.482358. The target-field geo is specified, as is a distance of 100 miles: this is the radius within which target-locations must reside, for their documents to be returned.

    {
      "from": 0,
      "size": 10,
      "query": {
        "location": {
          "lon": -2.235143,
          "lat": 53.482358
         },
          "distance": "100mi",
          "field": "geo"
        },
      "sort": [
        {
          "by": "geo_distance",
          "field": "geo",
          "unit": "mi",
          "location": {
          "lon": -2.235143,
          "lat": 53.482358
          }
        }
      ]
    }

    The query contains a sort object, which specifies that the returned documents should be ordered in terms of their geo_distance from specified lon and lat coordinates: these values need not be identical to those specified in the query object.

    A subset of formatted console output might appear as follows:

                .
                .
                .
    "hits": [
      {
        "index": "geoIndex_61d8c796ef7f4360_acbbef99",
        "id": "landmark_17411",
        "score": 1.4045076008239446e-06,
        "sort": [
          " \u0001?E#9>N\f\"e"
        ]
      },
      {
        "index": "geoIndex_61d8c796ef7f4360_acbbef99",
        "id": "landmark_17409",
        "score": 1.4045076008239446e-06,
        "sort": [
          " \u0001?O~i*(kD,"
        ]
      },
      {
        "index": "geoIndex_61d8c796ef7f4360_acbbef99",
        "id": "landmark_17403",
        "score": 1.4045076008239446e-06,
        "sort": [
          " \u0001?Sg*|/t\u001f\u0002"
        ]
      },
      {
        "index": "geoIndex_61d8c796ef7f4360_acbbef99",
        "id": "hotel_17413",
        "score": 1.4045076008239446e-06,
        "sort": [
          " \u0001?U]S\\.e\u0002_"
       ]
      },
                .
                .
                .

    Creating a Query: Rectangle-Based

    In the following query-body, the top_left of a rectangle is expressed by means of an array of two floating-point numbers; specifying a longitude of -2.235143 and a latitude of 53.482358. The bottom_right is expressed by means of key-value pairs; specifying a longitude of 28.955043, and a latitude of 40.991862. The results are specified to be sorted on name alone.

    {
      "from": 0,
      "size": 10,
      "query": {
        "top_left": [-2.235143, 53.482358],
        "bottom_right": {
          "lon": 28.955043,
          "lat": 40.991862
         },
        "field": "geo"
      },
      "sort": [
        "name"
      ]
    }

    A subset of formatted output might appear as follows:

              .
              .
              .
    "hits": [
      {
        "index": "geoIndex_61d8c796ef7f4360_acbbef99",
        "id": "landmark_17411",
        "score": 1.4045076008239446e-06,
        "sort": [
          " \u0001?E#9>N\f\"e"
        ]
      },
      {
        "index": "geoIndex_61d8c796ef7f4360_acbbef99",
        "id": "landmark_17409",
        "score": 1.4045076008239446e-06,
        "sort": [
          " \u0001?O~i*(kD,"
        ]
      },
      {
        "index": "geoIndex_61d8c796ef7f4360_acbbef99",
        "id": "landmark_17403",
        "score": 1.4045076008239446e-06,
        "sort": [
          " \u0001?Sg*|/t\u001f\u0002"
        ]
      },
      {
        "index": "geoIndex_61d8c796ef7f4360_acbbef99",
        "id": "hotel_17413",
        "score": 1.4045076008239446e-06,
        "sort": [
          " \u0001?U]S\\.e\u0002_"
        ]
      },
              .
              .
              .

    Creating a Query: Polygon-Based

    The following query-body uses an array, each of whose elements is a string, containing two floating-point numbers; to specify the latitude and longitude of each of the corners of a polygon — known as polygon points. In each string, the lat floating-point value precedes the lon.

    Here, the last-specified string in the array is identical to the initial string, thus explicitly closing the box. However, specifying an explicit closure in this way is optional: closure will be inferred by Couchbase Server, if not explicitly specified.

    If a target data-location falls within the box, its document is returned. The results are specified to be sorted on name alone.

    {
      "query": {
        "field": "geo",
        "polygon_points": [
          "37.79393211306212,-122.44234633404847",
          "37.77995881733997,-122.43977141339417",
          "37.788031092020155,-122.42925715405579",
          "37.79026946582319,-122.41149020154114",
          "37.79571192027403,-122.40735054016113",
          "37.79393211306212,-122.44234633404847"
        ]
      },
      "sort": [
        "name"
      ]
    }

    A subset of formatted output might appear as follows:

        .
        .
        .
        "hits": [
          {
            "index": "geoIndex_661ef3af66ee41b5_54820232",
            "id": "landmark_25944",
            "score": 0.3214575420492102,
            "sort": [
              "4"
            ]
          },
          {
            "index": "geoIndex_661ef3af66ee41b5_aa574717",
            "id": "landmark_25681",
            "score": 0.05294915340807584,
            "sort": [
              "alta"
            ]
          },
          {
            "index": "geoIndex_661ef3af66ee41b5_13aa53f3",
            "id": "landmark_25686",
            "score": 0.28955510851484045,
            "sort": [
              "atherton"
            ]
          },
            .
            .
            .