【问题标题】:How do I deserialize output from mongo-go-driver as bson array into a []interface{} when primitive.A is bson []interface当primitive.A是bson []interface时,如何将mongo-go-driver的输出作为bson数组反序列化到[]interface{}中
【发布时间】:2019-09-16 03:17:10
【问题描述】:

我有一个从使用新的 mongo-go-driver 的 mongo 查询生成的 map[string]interface{}

我想处理映射中的某些值并替换属于聚合键的值中的 £ 字符

这是地图:

result2 = map[aggregate:[map[£match:map[Source:Cities]] map[£sort:map[Order:1]]] collection:aggregate_stats db:stats]

遍历地图:

    for key, value := range result2 {
        fmt.Println("key from result2:", key, " || ", "value from result 2:", value)
        if key == "aggregate" {
            fmt.Println("FOUND AGGREGATE || ", "value:", value, " || type: ", reflect.TypeOf(value))
        }
        if valueMSI, ok := value.([]interface{}); ok {
            fmt.Println("Working", valueMSI)
            fmt.Println(reflect.TypeOf(valueMSI))
        }
    }

现在,在 if 语句中检查聚合键,第一个 print 语句的输出给出的类型为:

primitive.A

但打印时它似乎是地图的[]接口{}? [查看结果2]

考虑到这一点,为什么不评估第二个 if 语句?

这是否意味着primitive.A != 接口数组?

https://godoc.org/go.mongodb.org/mongo-driver/bson/primitive的文档中,A类型被定义为“一个A代表一个BSON数组。这种类型可以用来以简洁易读的方式来表示一个BSON数组。它一般应该在序列化为BSON时使用。对于反序列化时,应使用 RawArray 或 Array 类型。”

我该怎么做?我想访问聚合键的值?

【问题讨论】:

  • 为什么不使用value.(primitive.A)
  • @mkopriva 我们正在使用将 £ 转换为 $ 的函数来接受接口(因为它是一个具有此文件之外的范围的包)。所以理想情况下,我们希望一切都可以使用它
  • ... “这是否意味着primitive.A != 接口数组?” primitive.A 是一个接口切片[]interface{} 不是 same type 这就是您的 type assertion 失败的原因。它们确实共享相同的内存布局,因此将一种转换为另一种很容易,就像T(v)
  • 我明白你的意思,但我想问的是如何将 primitive.A 转换为 []interface{},因为它们本质上相似

标签: mongodb go bson


【解决方案1】:

您可以使用conversion expressionprimitive.A类型的值转换为[]interface{},其形式为T(x)

所以在你的情况下你可以这样做:

for key, value := range result2 {
    fmt.Println("key from result2:", key, " || ", "value from result 2:", value)
    if key == "aggregate" {
        fmt.Println("FOUND AGGREGATE || ", "value:", value, " || type: ", reflect.TypeOf(value))
    }
    if pa, ok := value.(primitive.A); ok {
        valueMSI := []interface{}(pa)
        fmt.Println("Working", valueMSI)
        fmt.Println(reflect.TypeOf(valueMSI))
    }
}

如文档中所述,您可以在任何这些情况下将非常量值 x 转换为类型 T(我已对与您的问题相关的情况进行了强调):

  • x 可分配给 T.
  • 忽略结构标签(见下文),x的类型和T有相同的 基础类型。
  • 忽略结构标记(见下文),x 的类型和 T 是指针类型 那些未定义的类型,它们的指针基类型有 相同的基础类型。
  • x 的类型和 T 都是整数或浮点类型。
  • x 的类型和 T 都是复杂类型。
  • x 是整数或字节切片或符文,T 是字符串类型。
  • x 是字符串,T 是字节或符文片段。

关于underlying types 的一些信息(已添加重点):

每个类型 T 都有一个基础类型:如果 T 是预先声明的类型之一 布尔、数字或字符串类型,或 类型文字, 对应的底层类型是 T 本身。否则,T 的底层 type 是 T 在其类型中引用的类型的基础类型 声明。

由于primitive.A 是使用类型文字 []interface{} 定义的,它具有与[]interface{} 相同的基础类型

  • []interface{} 的底层类型是[]interface{}
  • primitive.A 的底层类型是[]interface{}

【讨论】:

    猜你喜欢
    • 2020-09-26
    • 2019-01-05
    • 1970-01-01
    • 1970-01-01
    • 2016-02-14
    • 2011-09-02
    • 1970-01-01
    • 2021-11-26
    • 2017-04-10
    相关资源
    最近更新 更多