使用Golang和MongoDB实现的门店定位器

huangapple go评论114阅读模式
英文:

storelocator with golang and mongodb

问题

嗨,我正在尝试使用Golang和MongoDB构建一个店铺定位器。
我对这两个都不太熟悉。我尝试搜索,但是找不到一个在Golang中可以帮助我将带有名称和坐标的店铺插入到MongoDB中,并在提供的纬度和经度值的3000米半径范围内搜索店铺的代码。

注意:我想自己提供ID,这样我就可以轻松地通过ID获取店铺。

我尝试了下面给出的代码,但是没有任何反应,没有错误,也没有将店铺插入到数据库中。

test.go的代码如下:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "gopkg.in/mgo.v2"
  6. "gopkg.in/mgo.v2/bson"
  7. "log"
  8. )
  9. type Store struct {
  10. ID string `bson:"_id,omitempty" json:"shopid"`
  11. Name string `bson:"name" json:"name"`
  12. Location GeoJson `bson:"location" json:"location"`
  13. }
  14. type GeoJson struct {
  15. Type string `json:"-"`
  16. Coordinates []float64 `json:"coordinates"`
  17. }
  18. func main() {
  19. cluster := "localhost" // mongodb host
  20. // connect to mongo
  21. session, err := mgo.Dial(cluster)
  22. if err != nil {
  23. log.Fatal("could not connect to db: ", err)
  24. panic(err)
  25. }
  26. defer session.Close()
  27. session.SetMode(mgo.Monotonic, true)
  28. // search criteria
  29. long := 39.70
  30. lat := 35.69
  31. scope := 3000 // max distance in metres
  32. var results []Store // to hold the results
  33. // query the database
  34. c := session.DB("test").C("stores")
  35. // insert
  36. man := Store{}
  37. man.ID = "1"
  38. man.Name = "vinka medical store"
  39. man.Location.Type = "Point"
  40. man.Location.Coordinates = []float64{lat, long}
  41. // insert
  42. err = c.Insert(man)
  43. fmt.Printf("%v\n", man)
  44. if err != nil {
  45. fmt.Println("There is insert error")
  46. panic(err)
  47. }
  48. // ensure
  49. // Creating the indexes
  50. index := mgo.Index{
  51. Key: []string{"$2dsphere:location"},
  52. Bits: 26,
  53. }
  54. err = c.EnsureIndex(index)
  55. if err != nil {
  56. fmt.Println("There is index error")
  57. panic(err)
  58. }
  59. //find
  60. err = c.Find(bson.M{
  61. "location": bson.M{
  62. "$nearSphere": bson.M{
  63. "$geometry": bson.M{
  64. "type": "Point",
  65. "coordinates": []float64{long, lat},
  66. },
  67. "$maxDistance": scope,
  68. },
  69. },
  70. }).All(&results)
  71. //err = c.Find(bson.M{"_id": "1"}).All(&results)
  72. if err != nil {
  73. panic(err)
  74. }
  75. //convert it to JSON so it can be displayed
  76. formatter := json.MarshalIndent
  77. response, err := formatter(results, " ", " ")
  78. fmt.Println(string(response))
  79. }
英文:

Hey i am trying to build a store-locator using golang and mongodb .
I am new to both . I tried to search but was not able to find a code in golang which can help me insert store with name and co-ordinates into mongodb and then search for stores in a radius of 3000 meters of provided latitude and longitude value .

Note : i want to provide id by myself so that i can easily fetch stores if i have the id .

I tried as given below but nothing happens , no error or store insertion in db

test.go is as below :

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "gopkg.in/mgo.v2"
  6. "gopkg.in/mgo.v2/bson"
  7. "log"
  8. )
  9. type Store struct {
  10. ID string `bson:"_id,omitempty" json:"shopid"`
  11. Name string `bson:"name" json:"name"`
  12. Location GeoJson `bson:"location" json:"location"`
  13. }
  14. type GeoJson struct {
  15. Type string `json:"-"`
  16. Coordinates []float64 `json:"coordinates"`
  17. }
  18. func main() {
  19. cluster := "localhost" // mongodb host
  20. // connect to mongo
  21. session, err := mgo.Dial(cluster)
  22. if err != nil {
  23. log.Fatal("could not connect to db: ", err)
  24. panic(err)
  25. }
  26. defer session.Close()
  27. session.SetMode(mgo.Monotonic, true)
  28. // search criteria
  29. long := 39.70
  30. lat := 35.69
  31. scope := 3000 // max distance in metres
  32. var results []Store // to hold the results
  33. // query the database
  34. c := session.DB("test").C("stores")
  35. // insert
  36. man := Store{}
  37. man.ID = "1"
  38. man.Name = "vinka medical store"
  39. man.Location.Type = "Point"
  40. man.Location.Coordinates = []float64{lat, long}
  41. // insert
  42. err = c.Insert(man)
  43. fmt.Printf("%v\n", man)
  44. if err != nil {
  45. fmt.Println("There is insert error")
  46. panic(err)
  47. }
  48. // ensure
  49. // Creating the indexes
  50. index := mgo.Index{
  51. Key: []string{"$2dsphere:location"},
  52. Bits: 26,
  53. }
  54. err = c.EnsureIndex(index)
  55. if err != nil {
  56. fmt.Println("There is index error")
  57. panic(err)
  58. }
  59. //find
  60. err = c.Find(bson.M{
  61. "location": bson.M{
  62. "$nearSphere": bson.M{
  63. "$geometry": bson.M{
  64. "type": "Point",
  65. "coordinates": []float64{long, lat},
  66. },
  67. "$maxDistance": scope,
  68. },
  69. },
  70. }).All(&results)
  71. //err = c.Find(bson.M{"_id": "1"}).All(&results)
  72. if err != nil {
  73. panic(err)
  74. }
  75. //convert it to JSON so it can be displayed
  76. formatter := json.MarshalIndent
  77. response, err := formatter(results, " ", " ")
  78. fmt.Println(string(response))
  79. }

答案1

得分: 1

看起来Go语言在处理你的坐标时出现了问题,这是由于float64的精度问题导致的。

请检查以下内容:
如果你的经度为39.70,纬度为35.69,你需要设置scope=3000000才能选择到你的记录。
然而,如果你使用更精确的坐标,比如:

  1. long := 39.6910592
  2. lat := 35.6909623

那么即使设置范围为1米(预期的范围),你也能找到你的店铺。

祝好,
-D

英文:

@user7227958

Looks like Go is playing tricks with you due to (lack of) float64 preciseness of your coordinates.

Check this:
with long := 39.70 and lat := 35.69 you need a scope=3000000 for your record to be selected.
However if you'll use more precise coordinates, say

long := 39.6910592
lat := 35.6909623

then you'll be able to find your store even with a scope of 1 meter (which is expected).

Cheers,
-D

huangapple
  • 本文由 发表于 2016年11月30日 06:57:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/40877322.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定