将 MongoDB 中的对象数组转储到结构体切片中。

huangapple go评论88阅读模式
英文:

Dump a mongodb array of objects in a slice of struct

问题

我有一个包含其他字段的对象数组,存储在MongoDB文档中:

db.config.find({},{list_attributes:1, _id:0});
[
{
    list_attributes: {
    '0': { field: 'LASTNAME', field_key: 'lastname', dataType: 'text' },
    '1': { field: 'FIRSTNAME', field_key: 'firstname', dataType: 'text' },
    '2': { field: 'SMS', dataType: 'text' },
    '3': {
        field: 'DOUBLE_OPT-IN',
        dataType: 'category',
        order: 1,
        catAttrib: { '1': 'Yes', '2': 'No' }
    },
    '4': { field: 'OPT_IN', dataType: 'boolean', order: 2 },
    '5': { field: 'TEST_NUMBER', dataType: 'float', order: 3 },
    '6': { field: 'TEST_DATE', dataType: 'date', order: 4 }
    }
}
]

我想将这些数据转储到以下结构的切片中,使切片的第0个索引包含list_attributes数组的第0个对象:

type MongoFields struct {
    Field     string `bson:"field" json:"field"`
    FieldKey  string `bson:"field_key,omitempty" json:"field_key,omitempty"`
    DataType  string `bson:"data_type" json:"data_type"`
    Order     int    `bson:"order,omitempty" json:"order,omitempty"`
    CatAttrib bson.M `bson:"catAttrib,omitempty" json:"catAttrib,omitempty"`
}

我正在使用官方的Golang MongoDB驱动程序。

package main

import (
    "context"       // 管理多个请求
    "encoding/json" // 使用JSON编码为bson.M字符串
    "fmt"           // Println()函数
    "log"
    "reflect" // 获取对象类型

    // 导入'mongo-go-driver'包库
    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

type MongoFields struct {
    Field     string `bson:"field" json:"field"`
    FieldKey  string `bson:"field_key,omitempty" json:"field_key,omitempty"`
    DataType  string `bson:"data_type" json:"data_type"`
    Order     int    `bson:"order,omitempty" json:"order,omitempty"`
    CatAttrib bson.M `bson:"catAttrib,omitempty" json:"catAttrib,omitempty"`
}

func main() {

    // 声明主机和端口选项以传递给Connect()方法
    clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")

    // 连接到MongoDB并返回Client实例
    client, err := mongo.Connect(context.TODO(), clientOptions)
    if err != nil {
        fmt.Println("mongo.Connect() ERROR:", err)
        log.Fatal(err)
    }

    // 为MongoDB API调用声明Context对象
    ctx := context.Background()

    // 通过数据库访问MongoDB集合
    col := client.Database("SomeDatabase").Collection("Some Collection")

    // 典型的BSON Map过滤器
    //filter := bson.M{"int field": bson.M{"$gt":42}}

    // 使用`字符串转义引号创建字符串
    query := `{list_attributes:1, _id:0}`

    // 声明一个空的BSON Map对象
    var bsonMap bson.M

    // 使用JSON包的Unmarshal()方法
    err = json.Unmarshal([]byte(query), &bsonMap)
    if err != nil {
        panic(err)
    } else {
        fmt.Println("bsonMap:", bsonMap)
        fmt.Println("bsonMap TYPE:", reflect.TypeOf(bsonMap))
    }

    // 将解组的BSON映射嵌套在另一个BSON对象中
    filter := bson.M{"field": bsonMap}

    // 将过滤器传递给Find()以返回MongoDB游标
    cursor, err := col.Find(ctx, filter)
    if err != nil {
        log.Fatal("col.Find ERROR:", err)
    }

    // 打印游标对象
    fmt.Println("\ncursor TYPE:", reflect.TypeOf(cursor))
    fmt.Println("cursor:", cursor)

    // 遍历所有文档
    for cursor.Next(ctx) {
        var p MongoFields

        // 解码文档
        if err := cursor.Decode(&p); err != nil {
            log.Fatal("cursor.Decode ERROR:", err)
        }
        // 打印迭代的游标对象的结果
        fmt.Printf("\nMongoFields: %+v\n", p)
    }
}

我得到了以下错误:

panic: invalid character 'l' looking for beginning of object key string
goroutine 1 [running]:
main.main()
/home/arun/GolandProjects/storeInSlice/main.go:54 +0x6c5
英文:

I have an array of objects along with other fields in a mongodb document:

db.config.find({},{list_attributes:1, _id:0});
[
{
list_attributes: {
'0': { field: 'LASTNAME', field_key: 'lastname', dataType: 'text' },
'1': { field: 'FIRSTNAME', field_key: 'firstname', dataType: 'text' },
'2': { field: 'SMS', dataType: 'text' },
'3': {
field: 'DOUBLE_OPT-IN',
dataType: 'category',
order: 1,
catAttrib: { '1': 'Yes', '2': 'No' }
},
'4': { field: 'OPT_IN', dataType: 'boolean', order: 2 },
'5': { field: 'TEST_NUMBER', dataType: 'float', order: 3 },
'6': { field: 'TEST_DATE', dataType: 'date', order: 4 }
}
}
]

I want to dump this data in a slice of the following struct so that 0th index of slice contains the 0th object of list_attributes array:

type MongoFields struct {
Field     string `bson:"field" json:"field"`
FieldKey  string `bson:"field_key,omitempty" json:"field_key,omitempty"`
DataType  string `bson:"data_type" json:"data_type"`
Order     int    `bson:"order,omitempty" json:"order,omitempty"`
CatAttrib bson.M `bson:"catAttrib,omitempty" json:"catAttrib,omitempty"`
}

I am using the official mongodb driver for golang.

package main
import (
"context"       // manage multiple requests
"encoding/json" // Use JSON encoding for bson.M string
"fmt"           // Println() function
"log"
"reflect" // get an object type
// import 'mongo-go-driver' package libraries
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type MongoFields struct {
Field     string `bson:"field" json:"field"`
FieldKey  string `bson:"field_key,omitempty" json:"field_key,omitempty"`
DataType  string `bson:"data_type" json:"data_type"`
Order     int    `bson:"order,omitempty" json:"order,omitempty"`
CatAttrib bson.M `bson:"catAttrib,omitempty" json:"catAttrib,omitempty"`
}
func main() {
// Declare host and port options to pass to the Connect() method
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
// Connect to the MongoDB and return Client instance
client, err := mongo.Connect(context.TODO(), clientOptions)
if err != nil {
fmt.Println("mongo.Connect() ERROR:", err)
log.Fatal(err)
}
// Declare Context object for the MongoDB API calls
ctx := context.Background()
// Access a MongoDB collection through a database
col := client.Database("SomeDatabase").Collection("Some Collection")
// Typical BSON Map filter
//filter := bson.M{"int field": bson.M{"$gt":42}}
// Create a string using ` string escape ticks
query := `{list_attributes:1, _id:0}`
// Declare an empty BSON Map object
var bsonMap bson.M
// Use the JSON package's Unmarshal() method
err = json.Unmarshal([]byte(query), &bsonMap)
if err != nil {
panic(err)
} else {
fmt.Println("bsonMap:", bsonMap)
fmt.Println("bsonMap TYPE:", reflect.TypeOf(bsonMap))
}
// Nest the Unmarshalled BSON map inside another BSON object
filter := bson.M{"field": bsonMap}
// Pass the filter to Find() to return a MongoDB cursor
cursor, err := col.Find(ctx, filter)
if err != nil {
log.Fatal("col.Find ERROR:", err)
}
// Print cursor object
fmt.Println("\ncursor TYPE:", reflect.TypeOf(cursor))
fmt.Println("cursor:", cursor)
// iterate through all documents
for cursor.Next(ctx) {
var p MongoFields
// Decode the document
if err := cursor.Decode(&p); err != nil {
log.Fatal("cursor.Decode ERROR:", err)
}
// Print the results of the iterated cursor object
fmt.Printf("\nMongoFields: %+v\n", p)
}
}

I am getting:

panic: invalid character 'l' looking for beginning of object key string
goroutine 1 [running]:
main.main()
/home/arun/GolandProjects/storeInSlice/main.go:54 +0x6c5

答案1

得分: 1

您的查询JSON不是有效的JSON:

// 使用字符串转义符创建字符串 query := {list_attributes:1, _id:0}`

// 声明一个空的BSON Map对象
var bsonMap bson.M

// 使用JSON包的Unmarshal()方法
err = json.Unmarshal([]byte(query), &bsonMap)

有效的JSON应该是:

query := {"list_attributes":1, "_id":0}

但是使用复合字面量创建这样的投影更简单:

query := bson.M{
"list_attributes": 1,
"_id": 0,
}

这是一个定义投影的文档(列出您想要检索的字段)。这不应该与过滤文档相同。

要获取所有文档而不使用过滤器,请使用空文档,例如:

filter := bson.D{}
// 或者
filter := bson.M{}

英文:

Your query JSON is not valid JSON:

// Create a string using ` string escape ticks
query := `{list_attributes:1, _id:0}`
// Declare an empty BSON Map object
var bsonMap bson.M
// Use the JSON package's Unmarshal() method
err = json.Unmarshal([]byte(query), &bsonMap)

A valid JSON would be:

query := `{"list_attributes":1, "_id":0}`

But it's much simpler to use a composite literal to create such projection:

query := bson.M{
"list_attributes": 1,
"_id":             0,
}

And this is a document to define projection (list fields you want to retrieve). This should not be the same as the filter document.

To fetch all documents without a filter, use an empty document, e.g.:

filter := bson.D{}
// or 
filter := bson.M{}

huangapple
  • 本文由 发表于 2022年7月12日 17:26:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/72950009.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定