mongoDB处理方案
解决方案(新表)
建议新表开启mongoDB validator模式,在数据库层面能有效解决schema模糊造成的问题。
下面是mongoDBnvalidator的基本介绍。
mongoDB validator
为了解决这些类型模糊和字段缺失问题,mongoDB在3.2版本引入了Schema Validation,并在3.6版本中得到增强。我们线上DB的版本是3.2可以直接使用。
Schema Validator允许用户来自己定义document的校验格式。Schema Validator是作用在collection上面的,所以我们可以通过设置collection的属性来控制schema校验。
下面通过例子来讲解一下:
假设我们要建立新的sku
的collection,sku里面可能会有以下属性。
{
id: 900,
name: "玻璃杯",
description: "一个好看的玻璃杯",
details: {
weight: "470g",
color: "绿色",
material: "玻璃"
},
price: 100,
price_history: [
{
price: 80,
date: "2018-4-1"
},
{
price: 100,
date: "2018-4-5"
}
]
}
那么现在假设上面的字段都是必须的,我们由此来建立这个这个colletion的schema。
mongoDB的schema分为两种模式分别为strict
和moderate
,在strict
模式下,mongoDB会将shcema检测应用于所有的文档上面。而moderate
模式下,当进行UPDATE
操作时,只会应用于所有检测字段都已经满足条件的文档上面。
创建Schema
db.createCollection(
"sku",
"Validator": {"$and" : [
{
"id" : {
"$type" : "int",
"$exists" : true
}
},
{
"name" : {
"$type" : "string",
"$exists" : true
}
},
{
"description" : {
"$type" : "string",
"$exists" : true
}
},
{
"details" : {
"$type" : "object",
"$exists" : true
}
},
{
"details.weight" : {
"$type" : "string",
"$exists" : true
}
},
{
"details.color" : {
"$type" : "string",
"$exists" : true
}
},
{
"details.material" : {
"$type" : "string",
"$exists" : true
}
},
{
"price" : {
"$type" : "int",
"$exists" : true
}
},
{
"price_history" : {
"$type" : "array",
"$exists" : true
}
}
]
}
)
这样一个collection
就创建好了,schema默认是strict
模式。
非法格式的处理
对非法格式的处理,mongoDB提供了validationAction
这个参数来控制。默认为error
,当出现非法格式直接报错。用户可以修改为warn
,允许非法格式的更改,但对非法格式的修改记上日志。
解决方案(老表)
存在的问题
因为现在mongoDB集合数量巨大,每一个表都去仔细核对工作量太大。所以将存在的问题分为必须要解决的和可能需要解决的。
必须解决的问题,我总结了一下主要包括:
-
在金额和数量的字段,存在字符串类型,会直接引起系统报错。
-
某些重要字段的缺失,主要包括
station_id
、group_id
等。(这里只能间接的找,有可能找不到) -
完全不一致的字段类型,
array
和string
混用。
可能需要解决的问题:
-
对于数字类型的字段,几乎所有表都没有区分int和float类型。
-
存在大量的业务逻辑,就是通过字段是否存在来做判断,不同条件生成的文档不一样。
解决方案
对于上面必须解决的问题,首先修改代码,保证数据正常生成。经过测试如果数据生成无误,开启schema validator模式。保证以后的数据也正常生成。以前的脏数据,通过刷脚本解决。