ES中ignore_malformed参数故事版
ignore_malformed
ignore_malformed 可以忽略不规则的数据,该参数默认为 false
java#ignore_malformed DELETE users PUT users { "mappings": { "properties": { "birthday":{ "type": "date", "format": "yyyy-MM-dd||yyyy-MM-dd HH:mm:ss" }, "age":{ "type": "integer", "ignore_malformed": true } } } } PUT users/_doc/1 { "birthday":"2020-11-11", "age":99 } PUT users/_doc/2 { "birthday":"2020-11-11 11:11:11", "age":"abc" } GET users/_doc/2 PUT users/_doc/2 { "birthday":"2020-11-11 11:11:11aaa", "age":"abc" }
ignore_malformed:数字村的「宽容质检员」 🛂✨
想象数字村有个海关质检站,所有进口货物(数据)都要在这里接受检查。而 ignore_malformed
参数就是质检员的工作模式开关,决定了如何处理不合格的货物:
故事:两种质检模式
1. 严格模式(默认 false)
json
"age": {
"type": "integer",
"ignore_malformed": false // 默认值
}
质检员行为:
- 🔍 发现"abc"冒充数字 → 🚫 立即拒收整个货柜!
- ❌ 错误信息:
"reason": "For input string: \"abc\""
2. 宽容模式(设置 true)
json
"age": {
"type": "integer",
"ignore_malformed": true // 开启宽容模式
}
质检员行为:
- 🔍 发现"abc"冒充数字 → ⚠️ 单独隔离问题货物
- ✅ 放行其他合格货物
- 📦 问题货物存隔离仓(保留原始值但不使用)
实战场景演示
场景1:合格货物正常通行
json
PUT village/_doc/1
{
"birthday": "2020-11-11", // ✅ 合格日期
"age": 99 // ✅ 合格数字
}
结果:顺利通关,货物可搜索
场景2:混装货物宽容处理
json
PUT village/_doc/2
{
"birthday": "2020-11-11 11:11:11", // ✅ 合格日期
"age": "abc" // ❌ 假数字
}
宽容质检员:
- 放行
birthday
→ 可搜索 - 隔离
age
→ 不索引但存储 - 整批货物仍可查询(通过其他字段)
场景3:危险货物坚决拦截
json
PUT village/_doc/3
{
"birthday": "2020-11-11 11:11:11aaa", // ❌ 污染日期
"age": "abc" // ❌ 假数字
}
结果:
- 🚫 整批货物被拒收!
- 错误信息:
"reason": "failed to parse date field [...]"
核心规则图解
宽容质检员的秘密仓库
查看被隔离的货物
json
GET village/_doc/2
/* 返回:
{
"birthday": "2020-11-11 11:11:11",
"age": "abc" // ❌ 仍在仓库但无索引
} */
搜索测试
json
// 尝试搜索问题字段(失败)
GET village/_search
{
"query": {"term": {"age": "abc"}} // ❌ 无结果
}
// 搜索正常字段(成功)
GET village/_search
{
"query": {"match": {"birthday": "2020-11-11"}} // ✅ 找到文档
}
为什么需要宽容模式?
数据清洗场景
数据类型 | 问题示例 | 宽容模式价值 |
---|---|---|
用户年龄 | "未知"、"保密" | ✅ 保留其他信息 |
商品价格 | "面议"、"拍卖" | ✅ 忽略异常值 |
网络延迟 | "timeout" | ✅ 记录异常事件 |
传感器数据 | "ERR_001" | ✅ 保存错误代码 |
严格模式适用场景
json
// 金融交易系统(必须严格)
PUT bank_transactions
{
"mappings": {
"properties": {
"amount": {
"type": "scaled_float",
"scaling_factor": 100,
"ignore_malformed": false // 必须严格
}
}
}
}
避坑指南
坑1:日期格式宽容陷阱
json
"birthday": {
"type": "date",
"format": "yyyy-MM-dd", // 只定义一种格式
"ignore_malformed": true // 开启宽容
}
// 插入非常规格式 → 被宽容接受但不工作!
PUT data/_doc/1
{
"birthday": "2020/11/11" // ❌ 格式错误但被放行
}
// 解决方案:明确定义多种格式
"format": "yyyy-MM-dd||yyyy/MM/dd||epoch_millis"
坑2:跨字段污染
json
// 错误认知:以为宽容模式能救所有字段
PUT test/_doc/1
{
"valid_field": "正常值",
"malformed_field1": "abc", // 被宽容
"malformed_field2": "2020/11/11" // 未定义宽容 → 整批拒收!
}
// 解决方案:为每个字段单独设置
"malformed_field2": {
"type": "date",
"ignore_malformed": true
}
最佳实践配置
推荐方案:分层宽容策略
json
PUT smart_village
{
"mappings": {
"properties": {
// 核心字段(严格检查)
"user_id": {
"type": "keyword",
"ignore_malformed": false // 必须准确
},
// 次要字段(宽容处理)
"user_age": {
"type": "integer",
"ignore_malformed": true // 允许异常
},
// 日志类字段(完全宽容)
"error_message": {
"type": "text",
"ignore_malformed": true // 兼容各种乱码
}
}
}
}
记忆口诀
宽容质检三原则:
- 隔离代替拒收 → 保存问题货物
- 字段独立处理 → 不影响其他数据
- 原始值存仓库 → _source中可见
使用场景:
🟢 开宽容 → 日志/用户输入/传感器数据
🔴 关宽容 → 金融/交易/核心业务数据
特别注意:
⚠️ 日期字段要明确定义格式
⚠️ 每个字段需单独配置
记住这个质检员的比喻,轻松应对数据海洋中的"瑕疵品"! 🌊🔧