当primitive.A是bson []interface时,如何将mongo-go-driver作为bson数组的输出反序列化为[]interface{}

Sup*_*ork 4 go mongodb bson

我有一个从使用新 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]
Run Code Online (Sandbox Code Playgroud)

循环遍历地图:

    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))
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

primitive.A
Run Code Online (Sandbox Code Playgroud)

但它在打印时似乎是地图的 []interface{}?[见结果2]

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

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

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

我怎样才能做到这一点?我想访问聚合键的值?

mko*_*iva 5

您可以使用转换表达式将类型primitive.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))
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

关于基础类型的一点(强调):

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

由于primitive.A是使用所定义的类型字面 []interface{}它具有相同的基本类型[]interface{}

  • 的基础类型[]interface{}[]interface{}.
  • 的基础类型primitive.A[]interface{}.