Skip to content

Instantly share code, notes, and snippets.

@olivere
Created September 7, 2016 11:08
Show Gist options
  • Save olivere/2804a338bd743ac09942180000c6b325 to your computer and use it in GitHub Desktop.
Save olivere/2804a338bd743ac09942180000c6b325 to your computer and use it in GitHub Desktop.
Elastic geo distance query
package main
import (
"encoding/json"
"fmt"
"log"
"os"
elastic "gopkg.in/olivere/elastic.v3"
)
const (
indexName = "findmyfpstore"
typeName = "store"
)
type Location struct {
Lat float64 `json:"lat"`
Lon float64 `json:"lon"`
}
type Store struct {
Loc Location `json:"location"`
Address string `json:"address"`
Postal int `json:"postal"`
City string `json:"city"`
}
type Coord struct {
RequestId int `json:"request_id"`
Lat float64 `json:"lat"`
Lon float64 `json:"lon"`
}
func main() {
client, err := elastic.NewClient(
elastic.SetTraceLog(log.New(os.Stdout, "", 0)))
if err != nil {
log.Fatal(err)
}
// Setup the index
exists, err := client.IndexExists(indexName).Do()
if err != nil {
log.Fatal(err)
}
if exists {
// Drop the index
_, err = client.DeleteIndex(indexName).Do()
if err != nil {
log.Fatal(err)
}
}
// Create the index with a mapping
_, err = client.CreateIndex(indexName).BodyString(mapping).Do()
if err != nil {
log.Fatal(err)
}
// Add a point
_, err = client.Index().Index(indexName).Type(typeName).Id("1").BodyJson(&Store{
Loc: Location{Lat: 47, Lon: 2},
Address: "Marienplatz",
Postal: 80331,
City: "Munich",
}).Refresh(true).Do()
if err != nil {
log.Fatal(err)
}
distanceQuery := elastic.NewGeoDistanceQuery("location")
distanceQuery = distanceQuery.Lat(48.81433999999999)
distanceQuery = distanceQuery.Lon(2.3204906)
distanceQuery = distanceQuery.Distance("500km")
boolQuery := elastic.NewBoolQuery()
boolQuery = boolQuery.Must(elastic.NewMatchAllQuery())
boolQuery = boolQuery.Filter(distanceQuery)
src, err := boolQuery.Source()
if err != nil {
log.Fatal(err)
}
data, err := json.Marshal(src)
if err != nil {
log.Fatal(err)
}
got := string(data)
fmt.Println(got)
searchResult, err := client.Search().Index(indexName).Type(typeName).Query(boolQuery).Do()
if err != nil {
log.Fatal(err)
}
if searchResult.Hits.TotalHits > 0 {
fmt.Printf("Found a total of %d stores\n", searchResult.Hits.TotalHits)
for _, hit := range searchResult.Hits.Hits {
var s Store
err := json.Unmarshal(*hit.Source, &s)
if err != nil {
// deserialization failed
log.Fatal(err)
}
fmt.Printf("Store from - Address : " + s.Address + " ; City : " + s.City)
}
} else {
fmt.Print("Found no stores\n")
}
}
const mapping = `{
"settings":{
"number_of_shards":1,
"number_of_replicas":0
},
"mappings":{
"store":{
"properties":{
"address":{
"type":"string"
},
"postal":{
"type":"long"
},
"city":{
"type":"string"
},
"address":{
"type":"string"
},
"location":{
"type":"geo_point"
}
}
}
}
}`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment