donglilian0061 2019-02-16 20:00
浏览 106
已采纳

无法按2sphere查找元素

I am coming because I need to realize geocalculs, however, it doesn't work. I am currently using the package globalsign/mgo

From the doc we have this:

db.<collection>.find( { <location field> :
        { $near :
            { $geometry :
                { type : "Point" ,
                     coordinates : [ <longitude> , <latitude> ] } ,
                     $maxDistance : <distance in meters>,
                } 
            }
       }
  )

Query a 2dsphere index : https://docs.mongodb.com/manual/tutorial/query-a-2dsphere-index/ 2dsphere Indexes : https://docs.mongodb.com/manual/core/2dsphere/

So I have the following:

import (
    "github.com/globalsign/mgo/bson"
    "shared/models"
    "time"
)

type Address struct {
    ID                 *bson.ObjectId `protobuf:"bytes,1,opt,name=id,proto3" json:"_id,omitempty" bson:"_id"`
    IsArchived         bool           `protobuf:"varint,2,opt,name=IsArchived,proto3" json:"is_archived,omitempty" bson:"is_archived"`
    CreatedAt          time.Time      `protobuf:"varint,3,opt,name=CreatedAt,proto3" json:"created_at,omitempty" bson:"created_at"`
    UpdatedAt          time.Time      `protobuf:"varint,4,opt,name=UpdatedAt,proto3" json:"update_at,omitempty" bson:"updated_at"`
    PlaceID            *bson.ObjectId `protobuf:"bytes,5,opt,name=PlaceID,proto3" json:"place_id,omitempty" bson:"place_id"`
    CountryCode        string         `protobuf:"bytes,6,opt,name=CountryCode,proto3" json:"country_code,omitempty" bson:"country_code,omitempty"`
    AdministrativeArea string         `protobuf:"bytes,7,opt,name=AdministrativeArea,proto3" json:"administrative_area,omitempty" bson:"administrative_area,omitempty"`
    Locality           string         `protobuf:"bytes,8,opt,name=Locality,proto3" json:"locality,omitempty" bson:"locality,omitempty"`
    PostalCode         string         `protobuf:"bytes,9,opt,name=PostalCode,proto3" json:"postal_code,omitempty" bson:"postal_code,omitempty"`
    Thoroughfare       string         `protobuf:"bytes,10,opt,name=Thoroughfare,proto3" json:"thoroughfare,omitempty" bson:"thoroughfare,omitempty"`
    Premise            string         `protobuf:"bytes,11,opt,name=Premise,proto3" json:"premise,omitempty" bson:"premise,omitempty"`
    Location           GeoJson `protobuf:"bytes,12,opt,name=Location,proto3" json:"location,omitempty" bson:"location,omitempty"`
}

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

var addresses []*models.Address
collection := _session.DB(constants.DBName).C(documentName)
err := collection.Find(session, addressDocument, bson.M{
    "location": bson.M{
        "$near": bson.M{
            "$geometry": bson.M{
                "type":        "Point",
                "coordinates": []float64{ -115.172813, 36.101379 },
            },
            "$maxDistance": 5000000,
        },
    },
}) &addresses)

From this, I got the following error:

"error processing query: ns=DBNAME.addressDocumentTree: GEONEAR field=location maxdist=5e+06 isNearSphere=0 Sort: {} Proj: {} planner returned error: unable to find index for $geoNear query"

I ensure my index at the initialization of my program

// EnsureIndex
func EnsureAddressIndex(session *mgo.Session) error {

    _session := session.Copy()
    defer _session.Close()

    c := _session.DB(constants.DBName).C(addressDocument)
    // Might be needed one day
    pIndex := mgo.Index{
        Key:  []string{"location:2dsphere"},
        Bits: 26,
    }
    err := c.EnsureIndex(pIndex)
    if err != nil {
        return err
    }

    return nil
}

Any idea? I have more than 20k addresses and they all have lat/lng.

Edit 1

I tried to switch from globalsign/mgo to gopkg.in/mgo.v2 with no success

  • 写回答

1条回答 默认 最新

  • douwanc63652 2019-02-17 16:16
    关注

    Finally found the issue.. Actually, I wasn't creating the index in the right way..

    // EnsureIndex force ids to be unique
    func EnsureAddressIndex(session *mgo.Session) error {
    
        _session := session.Copy()
        defer _session.Close()
    
        c := _session.DB(constants.DBName).C(addressDocument)
        // Might be needed one day
        pIndex := mgo.Index{
            Key:  []string{"$2dsphere:location"},
            Bits: 26,
        }
        err := c.EnsureIndex(pIndex)
        if err != nil {
            return err
        }
    
        return nil
    }
    

    At the index declaration, I had the following line:

    pIndex := mgo.Index{
        Key:  []string{"location:2dsphere"},
        Bits: 26,
    }
    

    But the correct way to write it is

    pIndex := mgo.Index{
        Key:  []string{"$2dsphere:location"},
        Bits: 26,
    }
    

    Hope it helps !

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 广告联盟的兜底广告是什么意思
  • ¥15 如何证明高斯噪声的包络公式
  • ¥150 寻找王者荣耀开发作者,合作或者解答
  • ¥15 乳腺癌数据集 相关矩阵 特征选择
  • ¥15 我的游戏账号被盗取,请问我该怎么做
  • ¥15 通关usb3.0.push文件,导致usb频繁断连
  • ¥15 有没有能解决微信公众号,只能实时拍照,没有选择相册上传功能,我不懂任何技术,,有没有给我发个软件就能搞定的方法
  • ¥15 Pythontxt文本可视化
  • ¥15 如何基于Ryu环境下使用scapy包进行数据包构造
  • ¥15 springboot国际化