当前位置: 首页 > 面试题库 >

为什么我无法使用golang的mgo库找到ID?

郝玄天
2023-03-14
问题内容

我在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十六进制表示形式是否可用的值。

err = coll.FindId(bson.ObjectIdHex(message.ID)).One(&result)

对于相反的方向,您可以使用ObjectId.Hex()此答案中详细介绍的方法:从mgo查询获取ObjectIdHex值

与key关联的值"_id"的类型bson.ObjectId仅为a string

bson.M是一个类型map[string]interface{},因此您需要Type断言才能将id作为以下形式获取ObjectId:

objid, ok := m["_id"].(ObjectId)
if !ok {
    panic("Not ObjectId")
}

并且ObjectId具有一个ObjectId.Hex()可以完全返回您想要的方法的方法:对象ID作为“纯”十六进制字符串:

fmt.Println(objid.Hex())

备择方案objid可以简单地转换为,string因为其基础类型为string。因此,您可以使用许多其他选项将其转换为十六进制string:

hexid := fmt.Sprintf("%x", string(objid))

如果只想打印它,则可以直接执行以下操作:

fmt.Printf("%x", string(objid))

注意:将其转换为string非常重要,否则fmt程序包将调用其String()方法,该方法将产生类似的字符串,ObjectIdHex("537f700b537461b70c5f0000")而这将被转换为十六进制,这显然不是您想要的。

或者,您可以使用encoding/hex包和hex.EncodeToString()函数:

hexid := hex.EncodeToString([]byte(objid))

您在代码中所做的是一个简单的类型转换(给定message.ID为type
string),并且语法是有效的,因为的基础类型bson.ObjectIdstring,因此基本上将24个字符解释为bson.ObjectIdtype,但是它是无效ObjectId值,因为它将是24个字节而不是12个字节。



 类似资料:
  • 问题内容: 我尝试在MongoDB中找到我的用户,但是当我运行此代码时: 只是告诉我: 并且不要返回其他值! 非常感谢您的参与! 问题答案: 只是您应该在结构名称的开头使用大写字母!而且你也不需要 你可以写 : 祝好运 :))

  • 问题内容: 我不明白如何正确使用$ literal。我正在使用mgo.v2和mgo.v2 / bson包。 我使用上面的代码在mongodb中获取数据并正常工作,它给了我结果 我试图在golang中使用相同的内容,如下所示 上面的代码,抛出一个错误 紧急:错误查询:BadValue:点必须是数组或对象 所以我就这样替换了 但这也让我出错 紧急:此对象已经是运算符,不能用作文档表达式(在“坐标”处)

  • 我试图使用JNA从Java应用程序调用。dll文件。我得到以下异常:

  • 我使用MVC页面中的Kendo DatePicker值构建了一个模型: 但是,如果我输入值,而不是单击日历并选择日期,它在这里不会得到值。我怎样才能得到这个数据?

  • 问题内容: 很抱歉,如果这是一个noobie问题,但我找不到很好的答案。 要找到然后删除我可以使用的东西 但是为什么我不能像这样将结果通过管道传递给rm 就像我将其输送到grep 我从某处读到rm不会从stdin接收输入,因此我无法通过管道传输它,但这是什么意思?当我输入rm a.txt时,它会从标准输入中读取,就像我可以grep一样吗?还是stdin和命令行之间有区别。帮帮我! 问题答案: 要扩

  • 问题内容: 我正在尝试打开一个保存在源文件夹本身中的CSV文件名“ logger.csv”。 但是,这一直在给我一个“找不到文件”错误。 问题答案: 如果您现在就使用相对路径,则该文件需要存在于项目根目录中, 而不是 存在于java文件的目录中。 考虑以下层次结构: 不管用。 将 现在 的工作。(注意,该文件与src目录相邻。)