英文:
Mongodb storage and retreival in mongogo driver
问题
我正在尝试使用Mongo Go驱动程序将数据插入MongoDB并从中读取数据。我正在使用一个具有数据字段的结构体。当我将数据类型设置为接口时,我得到多个映射,而当我将其指定为映射的切片时,返回一个单独的映射。数据在MongoDB中是相似的。
为什么在尝试访问数据时会有差异呢?
英文:
I am trying to insert the data and read that data from mongodb using mongo go driver. I am using a struct which has a data field. When I am using the data type as interface I get multiple maps and when I specify it as slice of maps it returns a single map. The data is similar in 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)
}
Data stored is similar in both cases.
Why there is difference in data when we are trying to access it?
答案1
得分: 2
当你使用interface{}
时,这意味着你将选择权交给驱动程序,让它选择最适合表示从MongoDB接收到的数据的数据类型。
当你使用[]map[string]interface{}
时,你明确表示你想要一个映射的切片,其中每个映射可以表示一个文档。
当你使用interface{}
时,你什么也没有说。驱动程序将选择bson.A
来表示数组,选择bson.D
来表示文档。
bson.A
简单地是一个 []interface{}
,而 bson.D
是 []E
,其中 E
是
type E struct {
Key string
Value interface{}
}
所以基本上 bson.D
是一个键值对(属性)的有序列表。
因此,当你使用 interface{}
时,你得到的是一个切片的切片,而不是多个映射。类型信息不会被打印出来,fmt
包会将切片和映射都打印在方括号中。
如果你想要看到类型信息,可以像这样打印:
fmt.Printf("%#v\n", result.Data)
使用 []map[string]interface{}
时的输出:
[]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}}}
英文:
When you use interface{}
, that means you leave it up to the driver to choose any data type it sees best to represent the data that arrives from MongoDB.
When you use []map[string]interface{}
, you explicitly say you want a slice of maps, where each map can represent a document.
When you use interface{}
, you say nothing. The driver will choose bson.A
to represent arrays, and bson.D
to represent documents.
bson.A
is simply a []interface{}
, and bson.D
is []E
where E
is
type E struct {
Key string
Value interface{}
}
So basically bson.D
is an ordered list of key-value pairs (properties).
So when you use interface{}
, you get a slice of slices, not multiple maps. Type information is not printed, the fmt
package prints slices and maps both enclosed in square brackets.
If you want to see the types, print it like this:
fmt.Printf("%#v\n", result.Data)
Output when using []map[string]interface{}
:
[]map[string]interface {}{map[string]interface {}{"key1":"using specific type", "key2":123}}
Output when using interface{}
:
primitive.A{primitive.D{primitive.E{Key:"key1", Value:"using specific type"}, primitive.E{Key:"key2", Value:123}}}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论