Home > Back-end >  Return the unique address sorted by shortest distance to an input lat long in OpenSearch/ElasticSear
Return the unique address sorted by shortest distance to an input lat long in OpenSearch/ElasticSear

Time:12-06

I have a database with following sample.

  "_index" : "python-address-test",
    "_type" : "_doc",
    "_id" : "1",
    "_score" : 0.0,
    "_source" : {
      "address" : "Graha Blok A",
      "geohash6" : "qqgft0",
      "location" : {
        "lat" : -6.5881896,
        "lon" : 106.747485
      }
    }
  },
  {
    "_index" : "python-address-test",
    "_type" : "_doc",
    "_id" : "2",
    "_score" : 0.0,
    "_source" : {
      "address" : "Graha",
      "geohash6" : "qqgft0",
      "location" : {
        "lat" : -6.5895002,
        "lon" : 106.7488968
      }
    }
  },
  {
    "_index" : "python-address-test",
    "_type" : "_doc",
    "_id" : "3",
    "_score" : 0.0,
    "_source" : {
      "address" : "Graha",
      "geohash6" : "qqgft0",
      "location" : {
        "lat" : -6.5884867,
        "lon" : 106.749212

Expected Return shall be, where the address shall be unique

{Graha Block A, Graha}

I have written following code, and able to get the address with shortest distance to an input lat, long. However I was unable to get the Unique Address. Please advise

{ "size": 10, 
  "query": {
    "bool": {
      "must": {
        "geo_distance": {
          "distance": "1km",
          "location": [
            106.7485418,
            -6.5875987
          ]
        }
      },
      "filter": {"match" : {"geohash6" : "qqgft0"}}
    }
  },
  "sort": [
    "_score",
    {
      "_geo_distance": {
        "location": { 
          "lat":  -6.5875987,
          "lon": 106.7485418
        },
        "order":         "asc",
        "unit":          "m", 
        "distance_type": "plane" 
      }
    }
  ]
}

CodePudding user response:

You can use collapse query to only show 1 result per address:

https://www.elastic.co/guide/en/elasticsearch/reference/current/collapse-search-results.html

Here is the example code:

Mappings

PUT test_geo
{
  "mappings": {
    "properties": {
      "address": {
        "type": "text",
        "fields": {
          "keyword": {
            "type":"keyword"
          }
        }
      },
      "geohash6": {
        "type": "keyword"
      },
      "location": {
        "type": "geo_point"
      }
    }
  }
}

Documents

POST test_geo/_doc
{
  "address": "Graha Blok A",
  "geohash6": "qqgft0",
  "location": {
    "lat": -6.5881896,
    "lon": 106.747485
  }
}

POST test_geo/_doc
{
  "address": "Graha Blok A",
  "geohash6": "qqgft0",
  "location": {
    "lat": -6.5881896,
    "lon": 106.747485
  }
}

POST test_geo/_doc
{
  "address": "Graha",
  "geohash6": "qqgft0",
  "location": {
    "lat": -6.5895002,
    "lon": 106.7488968
  }
}

Query

GET test_geo/_search
{
  "size": 10,
  "collapse": {
    "field": "address.keyword"
  }, 
  "query": {
    "bool": {
      "must": {
        "geo_distance": {
          "distance": "1km",
          "location": [
            106.7485418,
            -6.5875987
          ]
        }
      },
      "filter": {
        "match": {
          "geohash6": "qqgft0"
        }
      }
    }
  },
  "sort": [
    "_score",
    {
      "_geo_distance": {
        "location": {
          "lat": -6.5875987,
          "lon": 106.7485418
        },
        "order": "asc",
        "unit": "m",
        "distance_type": "plane"
      }
    }
  ]
}

Results

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 3,
      "relation": "eq"
    },
    "max_score": null,
    "hits": [
      {
        "_index": "test_geo",
        "_id": "PBC34oQBtNG1OrZokQMs",
        "_score": 1,
        "_source": {
          "address": "Graha Blok A",
          "geohash6": "qqgft0",
          "location": {
            "lat": -6.5881896,
            "lon": 106.747485
          }
        },
        "fields": {
          "address.keyword": [
            "Graha Blok A"
          ]
        },
        "sort": [
          1,
          133.96461555682822
        ]
      },
      {
        "_index": "test_geo",
        "_id": "hHa34oQB5Gw0WET8m33u",
        "_score": 1,
        "_source": {
          "address": "Graha",
          "geohash6": "qqgft0",
          "location": {
            "lat": -6.5895002,
            "lon": 106.7488968
          }
        },
        "fields": {
          "address.keyword": [
            "Graha"
          ]
        },
        "sort": [
          1,
          215.04628939232288
        ]
      }
    ]
  }
}
  • Related