Использование $literal в Golang-mgo

Я не могу понять, как правильно использовать $literal. Я использую пакеты mgo.v2 и mgo.v2/bson.

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

Я использовал приведенный выше код для извлечения данных в 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"}}}}}

Над кодом выдает ошибку

паника: неверный запрос: BadValue: точка должна быть массивом или объектом

поэтому заменил вот так

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

но это также выдает мне ошибку

паника: этот объект уже является выражением оператора и не может использоваться в качестве выражения документа (в «координатах»)

моя полная работа показана по ссылке ниже моя работа здесь, пожалуйста, помогите мне решить эту проблему. Спасибо


person hari prasad    schedule 06.03.2017    source источник
comment
Можете ли вы показать больше своего кода, потому что ваша первая версия работает для меня?   -  person icza    schedule 06.03.2017
comment
Я добавил свою работу, как вы просили. У меня проблема с преобразованием кода из запроса MongoDB в Golang.   -  person hari prasad    schedule 06.03.2017


Ответы (1)


Чтобы быть полным, это то, что вы на самом деле пытаетесь сделать:

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}}}}},
})
person icza    schedule 06.03.2017
comment
Большое спасибо, работает нормально. Спасибо за разъяснение о точке, которая относится к центральной сфере. Я вижу, что вы изменили местоположение на location.coordinates, где я использовал $coordinates, что совершенно неверно. - person hari prasad; 06.03.2017
comment
location или location.coordinates работают нормально. Я не нашел в них никакой разницы, но проблема в $координатах, которые я должен использовать lat и long. Спасибо. - person hari prasad; 06.03.2017
comment
@hariprasad Да, я проверял, и оба работают нормально, но я счел более подходящим указать "location.coordinates". - person icza; 06.03.2017