duanjiwu0324 2018-09-05 14:03
浏览 450
已采纳

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

I have problems with queries on UUID filed in my mongo collection. Mongo document structure is like:

{
    "_id": {
        "$oid": "5acf7faff5f02b0001e9fda1"
    },
    "j": {
        "$uuid": "d0459793-3ec0-71fd-319e-b959af081db6"
    },
    "s": "ok",
    "creation_date": {
        "$date": "2018-04-12T15:47:59.003Z"
    }
}

I want to get document, passing j uuid (not ObjectID). I create mongo connection, and I get my collection, then I try to execute this query:

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)

but e is always equal to "not found".

m.ID is string of uuid without dashes- so I convert it to uuid.UUID.

Other queries like c.Find(bson.M{"s": "ok"}).All(&jobs) work fine, so I'm sure about connection & collection.

Using golang 1.11 & mongodb 3.6.

UPDATE:

When I do db.mycol.find() from mongo console result is a list of documents like:

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

so I tried to modify my query like this:

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

And still it does not return the document.

  • 写回答

3条回答 默认 最新

  • dongzhaobai5982 2018-09-05 14:33
    关注

    The j property in your MongoDB documents is of type BinData type 3, so using a filter where you match it against a string will never yield any results.

    Your second attempt is on the right track. Except that you are filtering for the UTF-8 byte sequences of the hex representation of the UUID string (this is how Go stores strings in memory, this is what a string -> []byte conversion yields). This again will never yield any results.

    And the reason is that the binary data you have to provide in bson.Binary is not the above mentioned value, but the raw bytes of the UUID.

    So what you have to do is hex-decode the UUID (which is given to you as the hex representation), and use this binary data.

    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)
    

    Note that you have to pass the UUID to hex.DecodeString() without dashes, so you don't even need any 3rd party libs to process the UUID strings you have.

    Also please note that gopkg.in/mgo.v2 is not maintained anymore. Instead use the community supported fork: github.com/globalsign/mgo.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵