英文:
$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("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}}}}},
})
The problem is not with your `"Point"` literal, it's just a mere coincidence. If you change it to `"Pt"` 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 "pass" it does not work.
This works for example:
"$centerSphere": []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
// ...
"$centerSphere": []interface{}{[]interface{}{myLong, myLat}, 10 / 6378.11}
The complete query:
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}}}}},
})
[1]: https://docs.mongodb.com/manual/reference/operator/query/centerSphere/#op._S_centerSphere
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论