【问题标题】:Marshal and umarshal BSON元帅和元帅 BSON
【发布时间】:2020-02-20 22:04:30
【问题描述】:

TL;DR:MongoDB 驱动程序是否提供一个函数来编组和解组文档的单个字段?

这是一个非常简单的问题,但这里有一些上下文:

我有一个工作人员负责在 2 个独立的数据库之间同步数据。当它收到一条事件消息,表明某个文档必须同步时,它会在主数据库中选择该文档,并将其复制到另一个数据库中(这是一个完全不同的数据库,而不是副本集)。

问题是:我不知道该文档的完整结构,因此为了保存数据,我必须在映射map[string]interface{}bson.M 中解组该文档,其工作方式相同。但这似乎有很多开销,要解组我什至不使用的所有这些数据,只是将其编组回另一个数据库。

所以我考虑创建一个结构,只存储该文档的二进制值,而不执行任何编组或解组以减少开销,如下所示:

type Document = map[string]Field

type Field struct {
    Type  bsontype.Type
    Value []byte
}

func (f Field) MarshalBSONValue() (bsontype.Type, []byte, error) {
    return f.Type, f.Value, nil
}

func (f *Field) UnmarshalBSONValue(btype bsontype.Type, value []byte) error {
    f.Type = btype
    f.Value = value
    return nil
}

使用这种结构,我确实可以减少需要解析的数据量,但是现在,我需要手动解组此文档中我需要使用的一个值。

所以我想知道 MongoDB 驱动程序是否有一些功能,例如:

// Hypothetical function to get the value of a BSON
var status string
if err := decodeBSON(doc['status'].Type, doc['status'].Value, &status); err != nil {
    return err
}

// Hypothetical function to set the value of a BSON
createdAt, err := encodeBSON(bsontype.Date, time.Now())
if err != nil {
    return err
}

doc["createdAt"] = Field{Type: bsontype.Date, Value: createdAt}

我怎样才能做到这一点?

【问题讨论】:

  • 查看 bson.Raw,尤其是 Raw.Lookup 和 Raw.Elements。

标签: mongodb go mongo-go


【解决方案1】:

代码中的Field 类型等同于驱动程序的bson.RawValue 类型。通过切换到RawValue,您可以使用RawValue.Unmarshal 方法解码各个字段并使用bson.MarshalValue 对字段进行编码,这将返回构建新RawValue 所需的两个组件(类型和数据)。

如何使用这些方法根据原始值更改字段的示例:代码中的Field 类型等同于驱动程序的bson.RawValue 类型。通过切换到RawValue,您可以使用RawValue.Unmarshal 方法解码各个字段并使用bson.MarshalValue 对字段进行编码,这将返回构建新RawValue 所需的两个组件(类型和数据)。

如何根据原始值更改字段而不解组原始文档的所有字段的示例:https://gist.github.com/divjotarora/06c5188138456070cee26024f223b3ee

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多