Mongodb bson方案的Virtuals性质

Mongodb bson方案的Virtuals性质,mongodb,go,struct,mgo,Mongodb,Go,Struct,Mgo,我总是在我的节点项目中使用mongoose来处理文档,并且希望在我的golang项目中使用相同的机制。我找不到最好的方法来实现这样的东西 我有一些从数据库中检索到的结构,并希望根据我的服务器配置(如IP地址等)添加字段。我希望避免每次获取此集合的文档时调用相同的函数。最简单的方法是向结构添加一个方法,该方法计算所需的值,并在需要时调用该方法 例如: type Person struct { FirstName string `bson:"firstName"` LastName

我总是在我的节点项目中使用mongoose来处理文档,并且希望在我的golang项目中使用相同的机制。我找不到最好的方法来实现这样的东西


我有一些从数据库中检索到的结构,并希望根据我的服务器配置(如IP地址等)添加字段。我希望避免每次获取此集合的文档时调用相同的函数。

最简单的方法是向结构添加一个方法,该方法计算所需的值,并在需要时调用该方法

例如:

type Person struct {
    FirstName string `bson:"firstName"`
    LastName  string `bson:"lastName"`
}

func (p *Person) Name() string {
    return p.FirstName + " " + p.LastName
}

func main() {
    p := &Person{FirstName: "Bob", LastName: "Archer"}
    fmt.Println(p.Name())
}
type Person struct {
    FirstName string `bson:"firstName"`
    LastName  string `bson:"lastName"`
    name      string
}

func (p *Person) SetBSON(raw bson.Raw) (err error) {
    type my Person
    if err = raw.Unmarshal((*my)(p)); err != nil {
        return
    }
    p.name = p.FirstName + " " + p.LastName
    return nil
}
这样做的好处是,
Name()
将始终返回“正确”的名称,即使您在检索文档后修改了名字或姓氏

如果您不想总是计算结果,可以将其存储在字段中,例如:

type Person struct {
    FirstName string `bson:"firstName"`
    LastName  string `bson:"lastName"`
    name      string
}

func (p *Person) Name() string {
    if p.name == "" {
        p.name = p.FirstName + " " + p.LastName
    }
    return p.name
}
请注意,当保存
Person
的值时,
name
字段不会被持久化,因为它不会被导出

如果您希望自动执行此操作(例如,您希望在从MongoDB获取文档时自动计算
名称
),则可以通过实现该接口编写自定义解组逻辑。自定义解组逻辑没有什么特别的,只是在执行默认封送逻辑后计算并设置
name
字段

例如:

type Person struct {
    FirstName string `bson:"firstName"`
    LastName  string `bson:"lastName"`
}

func (p *Person) Name() string {
    return p.FirstName + " " + p.LastName
}

func main() {
    p := &Person{FirstName: "Bob", LastName: "Archer"}
    fmt.Println(p.Name())
}
type Person struct {
    FirstName string `bson:"firstName"`
    LastName  string `bson:"lastName"`
    name      string
}

func (p *Person) SetBSON(raw bson.Raw) (err error) {
    type my Person
    if err = raw.Unmarshal((*my)(p)); err != nil {
        return
    }
    p.name = p.FirstName + " " + p.LastName
    return nil
}
如果希望导出
名称
字段,例如
名称
,则可以使用
-
bson标记值将此字段从保存到MongoDB中排除,例如:

type Person struct {
    FirstName string `bson:"firstName"`
    LastName  string `bson:"lastName"`
    Name      string `bson:"-"`
}

谢谢这个,它的工作,并将节省我很多工作!