在Go中从MySQL迁移到Mongo时处理NULL 设置问题

如何解决在Go中从MySQL迁移到Mongo时处理NULL 设置问题

设置

我使用MySQL启动了一个项目,因此,我的项目有一些帮助程序类型来帮助处理空值,包括在API上解组传入的数据,将数据输入到DB中,然后进行相反的操作,提取数据时从数据库中移出,并用上述数据响应API。

出于这个问题的目的,我们将处理代表字符的结构。

type Character struct {
    MongoID          primitive.ObjectID `bson:"_id" json:"-"`
    ID               uint64             `bson:"id" json:"id"`
    Name             string             `bson:"name" json:"name"`
    CorporationID    uint               `bson:"corporation_id" json:"corporation_id"`
    AllianceID       null.Uint           `bson:"alliance_id" json:"alliance_id,omitempty"`
    FactionID        null.Uint          `bson:"faction_id" json:"faction_id,omitempty"`
    SecurityStatus   float64            `bson:"security_status" json:"security_status"`
    NotModifiedCount uint               `bson:"not_modified_count" json:"not_modified_count"`
    UpdatePriority   uint               `bson:"update_priority" json:"update_priority"`
    Etag             null.String        `bson:"etag" json:"etag"`
    CachedUntil      time.Time          `bson:"cached_until" json:"cached_until"`
    CreatedAt        time.Time          `bson:"created_at" json:"created_at"`
    UpdatedAt        time.Time          `bson:"updated_at" json:"updated_at"`
}

我要专门研究null.Uint类型的AllianceID属性,该属性由以下结构表示:

// Uint is an nullable uint.
type Uint struct {
    Uint  uint
    Valid bool
}

在使用JSON和MySQL的API设置中(即我的设置,但这不是唯一的),这种结构使我能够轻松处理“可为空”的值,而不必处理指针。我一直听说,最好避免使用除结构指针(切片,结构切片,结构映射等)以外的指针。如果您有原始类型(int,bool,float等),请尝试避免使用指向该原始类型的指针。

此类型具有MarshalJSONUnmarshalJSONScanValue之类的函数,这些函数内部具有利用Vaild属性确定要返回的值类型的逻辑。在此设置下,这确实非常有效。

问题

经过研究,我发现Mongo比关系数据库更适合我,但是由于Mongo Document(Schemaless)的流动性,我很难理解如何处理以下情况:一个字段可能会丢失,或者我在MySQL中拥有的属性通常会为null,并且可以轻松解组此结构的顶部并在逻辑上使用辅助函数,该属性已得到处理。另外,当我建立与Mongo的连接并从MySQL中拉出几行并从这些行中在Mongo中创建Documents时,BSON层会整理联盟ID的整个类型并将其粘贴在数据库中。

示例:

    "alliance_id" : {
        "uint" : NumberLong(99007760),"valid" : true
    },

与MySQL中一样,实现Valuer接口的Value函数将被调用并返回99007760,这就是数据库中的值。

另一种情况是有效为假。在MySQL中,这将意味着一个空值,并且在调用Value函数时,它将返回nil并且mysql驱动程序将使用NULL

填充该字段

所以我的问题是我该怎么做?我是否需要从头开始并重建模型,并在应用程序中重做一些使用Valid属性并使用*Pointers的逻辑,还是可以使用这些帮助程序类型来做我想做的事情。

我确实想说我已经尝试在bson包上实现MarshallerUnmarshaller接口,并且文档中的alliane_id仍设置为该类型的json编码版本,因为我以上概述。我想指出这一点,以排除实现这些接口的任何建议。如果我要实现的目标与Mongo相反,请链接一些指南,这些指南可以帮助我实现我要实现的目标。

感谢所有可以提供帮助的人。

解决方法

处理此类可选字段的最简单方法是使用指针:

type Character struct {
    ID               *uint64             `bson:"id,omitempty" json:"id"`
    Name              string             `bson:"name" json:"name"`
    ...
}

以上,如果ID字段为非空,则将其写入。取消编组时,如果数据库记录具有值,则将其设置为非nil值。如果省略omitempty标志,则封送此结构会将null写入数据库。

对于字符串,如果为空,则可以使用omitempty来完全省略该字段。如果要存储空字符串,请省略omitempty

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-