問題內容
我正在嘗試插入數(shù)據并使用 mongo go 驅動程序從 mongodb 讀取該數(shù)據。我正在使用一個具有數(shù)據字段的結構。當我使用數(shù)據類型作為接口時,我會得到多個映射,當我將其指定為映射切片時,它會返回單個映射。 mongodb 中的數(shù)據類似。
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) }
登錄后復制
僅使用接口時
當使用地圖切片時
兩種情況下存儲的數(shù)據相似。
為什么當我們嘗試訪問數(shù)據時會出現(xiàn)數(shù)據差異?
正確答案
當您使用 interface{}
時,這意味著您將由驅動程序來選擇它認為最能代表從 mongodb 到達的數(shù)據的任何數(shù)據類型。
當您使用 []map[string]interface{}
時,您明確表示您想要一個地圖切片,其中每個地圖可以代表一個文檔。
當您使用 interface{}
時,您什么也不說。驅動程序將選擇 bson.a
來表示數(shù)組,并選擇 bson.d
來表示文檔。
bson.a
只是一個 [] 接口{}
,并且 bson.d
是 []e
其中 e
是
type e struct { key string value interface{} }
登錄后復制
所以基本上 bson.d
是鍵值對(屬性)的有序列表。
因此,當您使用 interface{}
時,您會得到一片切片,而不是多個地圖。不打印類型信息,fmt
包打印切片和地圖,兩者都括在方括號中。
如果您想查看類型,請像這樣打印:
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}}}
登錄后復制