Golang下mongoDB的自生_id和string的关系

关系

直接了当的说,原生的_id 和 string 二者之间不能直接转换。非原生 _id 则因具体而定。

原因

mongoDB 生成的 _id 是二进制数据;而不是 golang 的 string ;二进制转换成 string,必定输出乱码字符。如果写入DB时 _id 由用户生成,那么mongoDB保持原样写入DB,用户传入的类型是什么,此 _id 将是什么类型。DB不做任何修改。
mongoDB原生的 _id 查询是显示像这样

{ "_id" : ObjectId("5a6ae25f614ca7fb150ac1f6")}

中间显示的字符串是二进制的十六进制表示。同理,当查询时,传入十六进制字符串,要转换成 _id 的格式才能查询到正确结果

>db.col.find({"_id" : ObjectId("5a6ae25f614ca7fb150ac1f6")}) //right
>db.col.find({"_id" : "5a6ae25f614ca7fb150ac1f6"})  //查无此人

采用二进制的原因可能为了最小化存储空间吧。

解决办法

读取
在golang中使用byte数组或者使用bson.ObjectId,像这样

type Info struct {
    Id []byte `bson:"_id"`
}
//或者
type Info struct {
    Id bson.ObjectId `bson:"_id"`
}

如果使用byte数组,则需要自己转换成十六进制,才是查询时显示的16进制字符串来使用,相比还是建议直接使用 bson.ObjectId,得到的结果就是16进制字符串。

import "encoding/hex"
//func EncodeToString(src []byte) string
id := hex.EncodeToString(info.Id)

还有一种办法就是上面说的自己生成 _id ,这个成本略微大一点,因为它需要一个唯一 id 的生成器。


查询
读取时返回 _id 的16进制字符串,那么反过来查询请求自然也需要转换,golang中如下操作

idList := make([]bson.ObjectId, len(req.Id))
for i, id := range req.Id {
    idList[i] = bson.ObjectIdHex(id)
}
sel := bson.M{"_id": bson.M{"$in": idList}}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值