将Go结构体编组为BSON以供mongoimport使用。

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

Marshal Go Struct to BSON for mongoimport

问题

我有一个结构体切片,我想将其写入一个 BSON 文件,以便进行 mongoimport

这是我正在做的大致想法(使用 gopkg.in/mgo.v2/bson):

  1. type Item struct {
  2. ID string `bson:"_id"`
  3. Text string `bson:"text"`
  4. }
  5. items := []Item{
  6. {
  7. ID: "abc",
  8. Text: "def",
  9. },
  10. {
  11. ID: "uvw",
  12. Text: "xyz",
  13. },
  14. }
  15. file, err := bson.Marshal(items)
  16. if err != nil {
  17. fmt.Printf("Failed to marshal BSON file: '%s'", err.Error())
  18. }
  19. if err := ioutil.WriteFile("test.bson", file, 0644); err != nil {
  20. fmt.Printf("Failed to write BSON file: '%s'", err.Error())
  21. }

这段代码可以运行并生成文件,但格式不正确 - 它看起来像这样(使用 bsondump --pretty test.bson):

  1. {
  2. "1": {
  3. "_id": "abc",
  4. "text": "def"
  5. },
  6. "2": {
  7. "_id": "abc",
  8. "text": "def"
  9. }
  10. }

我认为它应该更像这样:

  1. {
  2. "_id": "abc",
  3. "text": "def"
  4. }
  5. {
  6. "_id": "abc",
  7. "text": "def"
  8. }

在 Go 中是否可以实现这个效果?我只是想生成一个 .bson 文件,就像你期望 mongodump 命令生成的那样,这样我就可以运行 mongoimport 命令并填充一个集合。

英文:

I have a slice of structs that I want to write to a BSON file for doing a mongoimport.

This a rough idea of what I'm doing (using gopkg.in/mgo.v2/bson):

  1. type Item struct {
  2. ID string `bson:"_id"`
  3. Text string `bson:"text"`
  4. }
  5. items := []Item{
  6. {
  7. ID: "abc",
  8. Text: "def",
  9. },
  10. {
  11. ID: "uvw",
  12. Text: "xyz",
  13. },
  14. }
  15. file, err := bson.Marshal(items)
  16. if err != nil {
  17. fmt.Printf("Failed to marshal BSON file: '%s'", err.Error())
  18. }
  19. if err := ioutil.WriteFile("test.bson", file, 0644); err != nil {
  20. fmt.Printf("Failed to write BSON file: '%s'", err.Error())
  21. }

This runs and generates the file, but it's not formatted correctly - instead it looks like this (using bsondump --pretty test.bson):

  1. {
  2. "1": {
  3. "_id": "abc",
  4. "text": "def"
  5. },
  6. "2": {
  7. "_id": "abc",
  8. "text": "def"
  9. }
  10. }

When I think it should look more like:

  1. {
  2. "_id": "abc",
  3. "text": "def"
  4. {
  5. }
  6. "_id": "abc",
  7. "text": "def"
  8. }

Is this possible to do in Go? I just want to generate a .bson file that you would expect a mongodump command to produce, so that I can run mongoimport and populate a colection.

答案1

得分: 1

你想要独立的BSON文档,所以需要逐个进行编组:

  1. buf := &bytes.Buffer{}
  2. for _, item := range items {
  3. data, err := bson.Marshal(item)
  4. if err != nil {
  5. fmt.Printf("无法编组BSON项:%v", err)
  6. }
  7. buf.Write(data)
  8. }
  9. if err := ioutil.WriteFile("test.bson", buf.Bytes(), 0644); err != nil {
  10. fmt.Printf("无法写入BSON文件:%v", err)
  11. }

运行bsondump --pretty test.bson,输出将会是:

  1. {
  2. "_id": "abc",
  3. "text": "def"
  4. }
  5. {
  6. "_id": "uvw",
  7. "text": "xyz"
  8. }
  9. 2022-02-09T10:23:44.886+0100 找到2个对象

请注意,如果直接写入文件,则不需要使用缓冲区:

  1. f, err := os.Create("test.bson")
  2. if err != nil {
  3. log.Panicf("os.Create失败:%v", err)
  4. }
  5. defer f.Close()
  6. for _, item := range items {
  7. data, err := bson.Marshal(item)
  8. if err != nil {
  9. log.Panicf("bson.Marshal失败:%v", err)
  10. }
  11. if _, err := f.Write(data); err != nil {
  12. log.Panicf("f.Write失败:%v", err)
  13. }
  14. }
英文:

You want independent BSON documents, so marshal the items individually:

  1. buf := &bytes.Buffer{}
  2. for _, item := range items {
  3. data, err := bson.Marshal(item)
  4. if err != nil {
  5. fmt.Printf("Failed to marshal BSON item: '%v'", err)
  6. }
  7. buf.Write(data)
  8. }
  9. if err := ioutil.WriteFile("test.bson", buf.Bytes(), 0644); err != nil {
  10. fmt.Printf("Failed to write BSON file: '%v'", err)
  11. }

Running bsondump --pretty test.bson, the output will be:

  1. {
  2. "_id": "abc",
  3. "text": "def"
  4. }
  5. {
  6. "_id": "uvw",
  7. "text": "xyz"
  8. }
  9. 2022-02-09T10:23:44.886+0100 2 objects found

Note that the buffer is not needed if you write directly to the file:

  1. f, err := os.Create("test.bson")
  2. if err != nil {
  3. log.Panicf("os.Create failed: %v", err)
  4. }
  5. defer f.Close()
  6. for _, item := range items {
  7. data, err := bson.Marshal(item)
  8. if err != nil {
  9. log.Panicf("bson.Marshal failed: %v", err)
  10. }
  11. if _, err := f.Write(data); err != nil {
  12. log.Panicf("f.Write failed: %v", err)
  13. }
  14. }

huangapple
  • 本文由 发表于 2022年2月9日 17:16:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/71046804.html
匿名

发表评论

匿名网友

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

确定