$literal usage in Golang-mgo

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

$literal usage in Golang-mgo

问题

我无法理解如何正确使用$literal。我正在使用mgo.v2和mgo.v2/bson包。

我使用以下代码从mongodb中获取数据,运行良好。它给我返回结果:

{ "location":{
"type":"Point",
"coordinates":[77.587073,12.958794]
}}

我尝试在golang中使用相同的代码,如下所示:

pipe := DB.C("store").Pipe([]bson.M{
{"$project":bson.M{"location":
bson.M{"type":
bson.M{"$literal":"Point"},"coordinates":[]interface{}{"$longitude","$latitude"}}}}}

上述代码会抛出错误:

panic: bad query: BadValue: Point must be an array or object

所以我将其替换为以下代码:

pipe := DB.C("store").Pipe([]bson.M{
{"$project":bson.M{"location":
bson.M{"$literal":
bson.M{"type":"Point"},"coordinates":[]interface{}{"$longitude","$latitude"}}}}})

但这也会抛出错误:

panic: this object is already an operator expression, and can't be used as a document expression (at 'coordinates')

你可以在下面的链接中查看我的完整工作:
我的工作在这里
请帮助我解决这个问题。谢谢!

英文:

I can't understand how to properly use $literal. I am using mgo.v2 and mgo.v2/bson package.

db.store.aggregate([
{"$project":{
    "location":{
        "type":{"$literal":"Point"},
        "coordinates":["$longitude","$latitude"]
    }}
},])

I used the above code to fetch data in mongodb and working fine.It gives me the result

 { "location":{
            "type":"Point",
            "coordinates":[77.587073,12.958794] 
        }}

I tried to use the same in golang and it is shown below

pipe :=DB.C("store").Pipe([]bson.M{
		{"$project":bson.M{"location":
		bson.M{"type":
		 bson.M{"$literal":"Point"},"coordinates":[]interface{}{"$longitude","$latitude"}}}}}

Above code, throws me an error

> panic: bad query: BadValue: Point must be an array or object

so I replaced it like this

pipe :=DB.C("store").Pipe([]bson.M{
		{"$project":bson.M{"location":
		bson.M{"$literal":
		 bson.M{"type":"Point"},"coordinates":[]interface{}{"$longitude","$latitude"}}}}})

but this also throws me an error

> panic: this object is already an operator expression, and can't be
> used as a document expression (at 'coordinates')

my complete work is shown in the below link
my work is here
please help me to solve this.
Thank you

答案1

得分: 0

为了完整起见,这是你实际尝试做的事情:

pipe := DB.C("store").Pipe([]bson.M{
    {"$project": bson.M{"location": bson.M{"type": bson.M{"$literal": "Point"}, "coordinates": []interface{}{"$longitude", "$latitude"}}}},
    {"$match": bson.M{"location": bson.M{"$geoWithin": bson.M{"$centerSphere": []interface{}{"$coordinates", 10 / 6378.11}}}}},
})

问题不在于你的"Point"字面量,这只是一个巧合。如果你将其更改为例如"Pt",你仍然会看到完全相同的错误消息。

错误消息中的Point指的是$centerSphere,它期望一个中心点和一个半径。而你尝试“传递”它的方式是不起作用的。

以下是一个有效的示例:

"$centerSphere": []interface{}{[]interface{}{1.0, 2.0}, 10 / 6378.11}

你原始的查询没有意义,因为你试图找到位置与自身距离在10公里以内的文档,这将匹配所有文档。

相反,你想要/应该查询与特定位置相距10公里以内的文档,并且可以将这个特定位置的坐标传递给$centerSphere

myLong, myLat := 10.0, 20.0

// ...

"$centerSphere": []interface{}{[]interface{}{myLong, myLat}, 10 / 6378.11}

完整的查询:

myLong, myLat := 10.0, 20.0
pipe := DB.C("store").Pipe([]bson.M{
    {"$project": bson.M{"location": bson.M{"type": bson.M{"$literal": "Point"}, "coordinates": []interface{}{"$longitude", "$latitude"}}}},
    {"$match": bson.M{"location.coordinates": bson.M{"$geoWithin": bson.M{"$centerSphere": []interface{}{[]interface{}{myLong, myLat}, 10 / 6378.11}}}}},
})

<details>
<summary>英文:</summary>

To be complete, this is what you actually try to do:


	pipe := DB.C(&quot;store&quot;).Pipe([]bson.M{
		{&quot;$project&quot;: bson.M{&quot;location&quot;: bson.M{&quot;type&quot;: bson.M{&quot;$literal&quot;: &quot;Point&quot;}, &quot;coordinates&quot;: []interface{}{&quot;$longitude&quot;, &quot;$latitude&quot;}}}},
		{&quot;$match&quot;: bson.M{&quot;location&quot;: bson.M{&quot;$geoWithin&quot;: bson.M{&quot;$centerSphere&quot;: []interface{}{&quot;$coordinates&quot;, 10 / 6378.11}}}}},
	})

The problem is not with your `&quot;Point&quot;` literal, it&#39;s just a mere coincidence. If you change it to `&quot;Pt&quot;` for example, you will still see the exact same error message.

The `Point` in the error message refers to [`$centerSphere`][1], which expects a center _point_ and a radius. And the way you try to &quot;pass&quot; it does not work.

This works for example:

    &quot;$centerSphere&quot;: []interface{}{[]interface{}{1.0, 2.0}, 10 / 6378.11}

Your original query does not make sense, as you try to find documents where the location is within 10 kilometers from _itself_, which would match all documents.

Instead you want to / should query documents which are within 10 kilometers of a _specific_ location, and you may pass the coordinates of this specific location to `$centerSphere`:

    myLong, myLat := 10.0, 20.0

    // ...

    &quot;$centerSphere&quot;: []interface{}{[]interface{}{myLong, myLat}, 10 / 6378.11}

The complete query:

	myLong, myLat := 10.0, 20.0
	pipe := DB.C(&quot;store&quot;).Pipe([]bson.M{
		{&quot;$project&quot;: bson.M{&quot;location&quot;: bson.M{&quot;type&quot;: bson.M{&quot;$literal&quot;: &quot;Point&quot;}, &quot;coordinates&quot;: []interface{}{&quot;$longitude&quot;, &quot;$latitude&quot;}}}},
		{&quot;$match&quot;: bson.M{&quot;location.coordinates&quot;: bson.M{&quot;$geoWithin&quot;: bson.M{&quot;$centerSphere&quot;: []interface{}{[]interface{}{myLong, myLat}, 10 / 6378.11}}}}},
	})


  [1]: https://docs.mongodb.com/manual/reference/operator/query/centerSphere/#op._S_centerSphere

</details>



huangapple
  • 本文由 发表于 2017年3月6日 15:20:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/42619702.html
匿名

发表评论

匿名网友

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

确定