猿问

如何使用 mgo(golang 客户端)查询 mongodb 中的 UUID 字段?

我在查询我的 mongo 集合中提交的 UUID 时遇到问题。Mongo文档结构如下:


{

    "_id": {

        "$oid": "5acf7faff5f02b0001e9fda1"

    },

    "j": {

        "$uuid": "d0459793-3ec0-71fd-319e-b959af081db6"

    },

    "s": "ok",

    "creation_date": {

        "$date": "2018-04-12T15:47:59.003Z"

    }

}

我想获取文档,传递juuid(不是 ObjectID)。我创建了 mongo 连接,并获取了我的集合,然后我尝试执行此查询:


import (    

       mgo "gopkg.in/mgo.v2"

       "gopkg.in/mgo.v2/bson"

)

...

var job *Job

uid, _ := uuid.FromString(m.ID)

e := c.Find(bson.M{"j": uid.String()}).One(&job)

但e始终等于“未找到”。


m.ID是没有破折号的 uuid 字符串-,所以我将它转换为uuid.UUID.


其他查询c.Find(bson.M{"s": "ok"}).All(&jobs)工作正常,所以我确定连接和收集。


使用 golang 1.11 和 mongodb 3.6。


更新:


当我db.mycol.find()从 mongo 控制台执行时,结果是一个文档列表,例如:


{ "_id" : ObjectId("5acf5b0ac7fb0700010040ac"), "j" : BinData(3,"amOjUW1oQQ6dNsvLrQuDhg=="), "s" : "ok", "creation_date" : ISODate("2018-04-12T13:11:38.365Z") }

所以我试着像这样修改我的查询:


e := c.Find(bson.M{"j": bson.Binary{0x03, []byte(m.ID)}}).One(&job)

而且它仍然不返回文件。


倚天杖
浏览 132回答 3
3回答

潇潇雨雨

MongoDB 文档中的属性j是类型BinData3,因此在将它与字符串匹配时使用过滤器永远不会产生任何结果。你的第二次尝试是在正确的轨道上。除了您要过滤 UUID 字符串的十六进制表示的 UTF-8 字节序列(这是 Go 在内存中存储字符串的方式,这是 -> 转换产生的结果string)[]byte。这将永远不会产生任何结果。原因是您必须提供的二进制数据bson.Binary不是上述值,而是 UUID 的原始字节。因此,您要做的是对 UUID(以十六进制表示形式提供给您)进行十六进制解码,并使用此二进制数据。data, err := hex.DecodeString(m.ID)if err != nil {    panic(err)}e := c.Find(bson.M{"j": bson.Binary{    Kind: bson.BinaryUUIDOld,    Data: data,}}).One(&job)请注意,您必须将 UUID 传递给hex.DecodeString()不带破折号的,因此您甚至不需要任何第三方库来处理您拥有的 UUID 字符串。另请注意,gopkg.in/mgo.v2不再维护。而是使用社区支持的 fork: github.com/globalsign/mgo。

达令说

如果您有要查询的 GUID,则转换对我有用(重新排序密钥字节,然后转换为十六进制解码):func CsuuidToBinary(key string) []byte {    hexStr := strings.Replace(key, "-", "", -1)    first := hexStr[6:8] + hexStr[4:6] + hexStr[2:4] + hexStr[0:2]    second := hexStr[10:12] + hexStr[8:10]    third := hexStr[14:16] + hexStr[12:14]    fourth := hexStr[16:len(hexStr)]    hexStr = first + second + third + fourth    data, _ := hex.DecodeString(hexStr)    return data}进而:    data := CsuuidToBinary(guidKey)    var a A    err := collection.Find(bson.M{"SomeKey": bson.Binary{Kind: 0x03, Data: data,}}).One(&a)

慕尼黑的夜晚无繁华

这是因为 UUID 存储为二进制数据,您需要将其转换为字符串才能查询它
随时随地看视频慕课网APP

相关分类

Go
我要回答