問題內容
我正在嘗試插入數據并使用 mongo go 驅動程序從 mongodb 讀取該數據。我正在使用一個具有數據字段的結構。當我使用數據類型作為接口時,我會得到多個映射,當我將其指定為映射切片時,它會返回單個映射。 mongodb 中的數據類似。
package main
import (
"context"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type Host struct {
Hostname string `bson:"hostname"`
Data []map[string]interface{} `bson:"data"` //return single map
// Data interface{} `bson:"data"` //returns multiple maps
}
func main() {
// Set up a MongoDB client
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
client, err := mongo.Connect(context.Background(), clientOptions)
if err != nil {
panic(err)
}
// Set up a MongoDB collection
collection := client.Database("testdb").Collection("hosts")
// Create a host object to insert into the database
host := Host{
Hostname: "example.com",
Data: []map[string]interface{}{
{"key1": "using specific type", "key2": 123},
},
}
// Insert the host object into the collection
_, err = collection.InsertOne(context.Background(), host)
if err != nil {
panic(err)
}
// Query the database for the host object
filter := bson.M{"hostname": "example.com"}
var result Host
err = collection.FindOne(context.Background(), filter).Decode(&result)
if err != nil {
panic(err)
}
// Print the host object
fmt.Println(result)
}
登錄后復制
僅使用接口時
當使用地圖切片時
兩種情況下存儲的數據相似。
為什么當我們嘗試訪問數據時會出現數據差異?
正確答案
當您使用 interface{} 時,這意味著您將由驅動程序來選擇它認為最能代表從 mongodb 到達的數據的任何數據類型。
當您使用 []map[string]interface{} 時,您明確表示您想要一個地圖切片,其中每個地圖可以代表一個文檔。
當您使用 interface{} 時,您什么也不說。驅動程序將選擇 bson.a 來表示數組,并選擇 bson.d 來表示文檔。
bson.a 只是一個 [] 接口{},并且 bson.d 是 []e 其中 e 是
type e struct {
key string
value interface{}
}
登錄后復制
所以基本上 bson.d 是鍵值對(屬性)的有序列表。
因此,當您使用 interface{} 時,您會得到一片切片,而不是多個地圖。不打印類型信息,fmt 包打印切片和地圖,兩者都括在方括號中。
如果您想查看類型,請像這樣打?。?/p>
fmt.printf("%#v\n", result.data)
登錄后復制
使用[]map[string]接口{}時的輸出:
[]map[string]interface {}{map[string]interface {}{"key1":"using specific type", "key2":123}}
登錄后復制
使用 interface{} 時的輸出:
primitive.A{primitive.D{primitive.E{Key:"key1", Value:"using specific type"}, primitive.E{Key:"key2", Value:123}}}
登錄后復制






