我在golang中使用mgo库进行mongo操作,这是我的代码:
session.SetMode(mgo.Monotonic, true) coll := session.DB("aaaw_web").C("cron_emails") var result Result fmt.Printf("%v", message.ID) err = coll.FindId(bson.ObjectId(message.ID)).One(&result) fmt.Printf("%v", result) fmt.Println(err)
我得到这个输出:
595f2c1a6edcba0619073263 {ObjectIdHex("") 0 0 0 0 { 0 false 0 } 0 0 0 0 0 0 0} ObjectIDs must be exactly 12 bytes long (got 24) not found
但是我检查了一下,文档存在于mongo中,但是到这里没有结果,我不知道我在想什么…
如错误消息所提示,对象ID的长度恰好为12个字节(12个字节的数据)。您看到的24个字符长的ID是ID的12个字节的十六进制表示形式(1个字节=> 2个十六进制数字)。
使用该bson.ObjectIdHex()函数获取bson.ObjectId十六进制表示形式是否可用的值。
bson.ObjectIdHex()
bson.ObjectId
err = coll.FindId(bson.ObjectIdHex(message.ID)).One(&result)
对于相反的方向,您可以使用ObjectId.Hex()此答案中详细介绍的方法:从mgo查询获取ObjectIdHex值
ObjectId.Hex()
与key关联的值"_id"的类型bson.ObjectId仅为a string。
"_id"
a string
bson.M是一个类型map[string]interface{},因此您需要Type断言才能将id作为以下形式获取ObjectId:
是一个类型
,因此您需要Type断言才能将id作为以下形式获取
objid, ok := m["_id"].(ObjectId) if !ok { panic("Not ObjectId") }
并且ObjectId具有一个ObjectId.Hex()可以完全返回您想要的方法的方法:对象ID作为“纯”十六进制字符串:
ObjectId
fmt.Println(objid.Hex())
备择方案objid可以简单地转换为,string因为其基础类型为string。因此,您可以使用许多其他选项将其转换为十六进制string:
hexid := fmt.Sprintf("%x", string(objid))
如果只想打印它,则可以直接执行以下操作:
fmt.Printf("%x", string(objid))
注意:将其转换为string非常重要,否则fmt程序包将调用其String()方法,该方法将产生类似的字符串,ObjectIdHex("537f700b537461b70c5f0000")而这将被转换为十六进制,这显然不是您想要的。
string
fmt
String()
ObjectIdHex("537f700b537461b70c5f0000")
或者,您可以使用encoding/hex包和hex.EncodeToString()函数:
hexid := hex.EncodeToString([]byte(objid))
您在代码中所做的是一个简单的类型转换(给定message.ID为type string),并且语法是有效的,因为的基础类型bson.ObjectId为string,因此基本上将24个字符解释为bson.ObjectIdtype,但是它是无效ObjectId值,因为它将是24个字节而不是12个字节。
message.ID