为什么在将Go结构中的数组字段插入到MongoDB数据库时,默认为null?

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

Why does an array field in a Go struct default to null when inserted into mongoDB database?

问题

所以,当我将一个模型插入到MongoDB中时,遇到了一些意外的行为。当我通过Postman向我的服务器发送一个空的请求体,并将其插入到数据库中时,返回给Postman的结果中,namenumber字段的默认值都是预期的默认值0"",但是对于data字段,它的默认值不是一个空数组,而是null,尽管在Go控制台中插入之前和之后打印出来的值都不是nil,而是一个空数组。在插入之前将data字段赋值为空的[]int{}可以解决这个问题,手动从Postman发送一个空数组作为data字段也可以解决,但我想知道是否还有其他方法可以确保数组字段在插入时默认为[]而不是null

这是我的模型:

type Test struct{
    Name string `json:"name" bson:"name"`
    Number int  `json:"number" bson:"number"`
    Data []int  `json:"data" bson:"data"`
}
英文:

So I have ran into some unexpected behavior when inserting a model into mongoDB. When I send an empty body via Postman to my server and insert it into my database, the returned result to Postman had name and number default to their expected default values, 0 and "", but for data, instead of defaulting to an empty array, it defaulted to null instead, even though its value printed out before and after insertion in the Go console isn't nil, but an empty array. Assigning the data field an empty []int{} before insertion solves the issue, and so does manually sending an empty array as the data field from Postman, but I was curious if there was any other way to guarantee that array fields default to [] and not null when getting inserted.

Here is my model:

type Test struct{
	Name string `json:"name"   bson:"name"`
	Number int  `json:"number" bson:"number"`
	Data []int  `json:"data"   bson:"data"`
}

答案1

得分: 1

package main

import (
	"log"

	"go.mongodb.org/mongo-driver/bson"
)

type Test struct {
	Data []int `json:"data" bson:"data"`
}

func (t *Test) MarshalBSON() ([]byte, error) {
	if t.Data == nil {
		log.Println("t.Data is nil")
		t.Data = make([]int, 0)
	}

	type my Test
	return bson.Marshal((*my)(t))
}

func main() {
	h := Test{}
	data, _ := bson.Marshal(&h)
	log.Print(bson.Raw(data))
}

// 输出:
// 2009/11/10 23:00:00 t.Data is nil
// 2009/11/10 23:00:00 {"data": []}

演示 Go Playground 链接:https://go.dev/play/p/1WlO_44hnco

另外,你可以查看这个链接:https://stackoverflow.com/questions/71902455/autofill-created-at-and-updated-at-in-golang-struct-while-pushing-into-mongodb

英文:

> Implement bson.Marshaler, and your MarshalBSON() function will be called when you save values

package main

import (
	"log"

	"go.mongodb.org/mongo-driver/bson"
)

type Test struct {
	Data []int `json:"data" bson:"data"`
}

func (t *Test) MarshalBSON() ([]byte, error) {
	if t.Data == nil {
		log.Println("t.Data is nil")
		t.Data = make([]int, 0)
	}

	type my Test
	return bson.Marshal((*my)(t))
}

func main() {
	h := Test{}
	data, _ := bson.Marshal(&h)
	log.Print(bson.Raw(data))
}

// output: 
// 2009/11/10 23:00:00 t.Data is nil
// 2009/11/10 23:00:00 {"data": []}

demo go playground link: https://go.dev/play/p/1WlO_44hnco

also, you can check this link: https://stackoverflow.com/questions/71902455/autofill-created-at-and-updated-at-in-golang-struct-while-pushing-into-mongodb

答案2

得分: 0

你可以使用mgocompat包为你的集合(或数据库)定义一个注册表。

import "go.mongodb.org/mongo-driver/bson/mgocompat"

...........
    
db := client.Database(dbName, options.Database().SetRegistry(mgocompat.NewRegistryBuilder().Build()))
英文:

You can define a registry for your collection (or database) using mgocompat package.

import "go.mongodb.org/mongo-driver/bson/mgocompat"

...........
    
db := client.Database(dbName, options.Database().SetRegistry(mgocompat.NewRegistryBuilder().Build()))

huangapple
  • 本文由 发表于 2022年6月23日 11:22:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/72724175.html
匿名

发表评论

匿名网友

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

确定