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

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

storelocator with golang and mongodb

问题

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

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

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

test.go的代码如下:

package main

import (
	"encoding/json"
	"fmt"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"log"
)

type Store struct {
	ID       string  `bson:"_id,omitempty" json:"shopid"`
	Name     string  `bson:"name" json:"name"`
	Location GeoJson `bson:"location" json:"location"`
}

type GeoJson struct {
	Type        string    `json:"-"`
	Coordinates []float64 `json:"coordinates"`
}

func main() {
	cluster := "localhost" // mongodb host

	// connect to mongo
	session, err := mgo.Dial(cluster)
	if err != nil {
		log.Fatal("could not connect to db: ", err)
		panic(err)
	}
	defer session.Close()
	session.SetMode(mgo.Monotonic, true)

	// search criteria
	long := 39.70
	lat := 35.69
	scope := 3000 // max distance in metres

	var results []Store // to hold the results

	// query the database
	c := session.DB("test").C("stores")

	// insert
	man := Store{}
	man.ID = "1"
	man.Name = "vinka medical store"
	man.Location.Type = "Point"
	man.Location.Coordinates = []float64{lat, long}

	// insert
	err = c.Insert(man)
	fmt.Printf("%v\n", man)
	if err != nil {
		fmt.Println("There is insert error")
		panic(err)
	}

	// ensure
	// Creating the indexes
	index := mgo.Index{
		Key:  []string{"$2dsphere:location"},
		Bits: 26,
	}
	err = c.EnsureIndex(index)
	if err != nil {
		fmt.Println("There is index error")
		panic(err)
	}

	//find
	err = c.Find(bson.M{
		"location": bson.M{
			"$nearSphere": bson.M{
				"$geometry": bson.M{
					"type":        "Point",
					"coordinates": []float64{long, lat},
				},
				"$maxDistance": scope,
			},
		},
	}).All(&results)

	//err = c.Find(bson.M{"_id": "1"}).All(&results)
	if err != nil {
		panic(err)
	}

	//convert it to JSON so it can be displayed
	formatter := json.MarshalIndent
	response, err := formatter(results, " ", "   ")

	fmt.Println(string(response))
}
英文:

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 :

package main
import (
"encoding/json"
"fmt"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"log"
)
type Store struct {
ID       string  `bson:"_id,omitempty" json:"shopid"`
Name     string  `bson:"name" json:"name"`
Location GeoJson `bson:"location" json:"location"`
}
type GeoJson struct {
Type        string    `json:"-"`
Coordinates []float64 `json:"coordinates"`
}
func main() {
cluster := "localhost" // mongodb host
// connect to mongo
session, err := mgo.Dial(cluster)
if err != nil {
log.Fatal("could not connect to db: ", err)
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
// search criteria
long := 39.70
lat := 35.69
scope := 3000 // max distance in metres
var results []Store // to hold the results
// query the database
c := session.DB("test").C("stores")
// insert
man := Store{}
man.ID = "1"
man.Name = "vinka medical store"
man.Location.Type = "Point"
man.Location.Coordinates = []float64{lat, long}
// insert
err = c.Insert(man)
fmt.Printf("%v\n", man)
if err != nil {
fmt.Println("There is insert error")
panic(err)
}
// ensure
// Creating the indexes
index := mgo.Index{
Key:  []string{"$2dsphere:location"},
Bits: 26,
}
err = c.EnsureIndex(index)
if err != nil {
fmt.Println("There is index error")
panic(err)
}
//find
err = c.Find(bson.M{
"location": bson.M{
"$nearSphere": bson.M{
"$geometry": bson.M{
"type":        "Point",
"coordinates": []float64{long, lat},
},
"$maxDistance": scope,
},
},
}).All(&results)
//err = c.Find(bson.M{"_id": "1"}).All(&results)
if err != nil {
panic(err)
}
//convert it to JSON so it can be displayed
formatter := json.MarshalIndent
response, err := formatter(results, " ", "   ")
fmt.Println(string(response))
}

答案1

得分: 1

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

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

	long := 39.6910592
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:

确定