ELK系列(4) - Elasticsearch cannot write xcontent for unknown value of type class java.math.BigDecimal
问题与分析
在使用Elasticsearch进行index数据时,发现报错如下:
java.lang.IllegalArgumentException: cannot write xcontent for unknown value of type class java.math.BigDecimal
at org.elasticsearch.common.xcontent.XContentBuilder.unknownValue(XContentBuilder.java:755)
at org.elasticsearch.common.xcontent.XContentBuilder.value(XContentBuilder.java:726)
at org.elasticsearch.common.xcontent.XContentBuilder.field(XContentBuilder.java:711)
at org.elasticsearch.index.query.BaseTermQueryBuilder.doXContent(BaseTermQueryBuilder.java:154)
at org.elasticsearch.index.query.AbstractQueryBuilder.toXContent(AbstractQueryBuilder.java:82)
at org.elasticsearch.index.query.BoolQueryBuilder.doXArrayContent(BoolQueryBuilder.java:275)
at org.elasticsearch.index.query.BoolQueryBuilder.doXContent(BoolQueryBuilder.java:256)
at org.elasticsearch.index.query.AbstractQueryBuilder.toXContent(AbstractQueryBuilder.java:82)
at org.elasticsearch.common.xcontent.XContentBuilder.value(XContentBuilder.java:779)
at org.elasticsearch.common.xcontent.XContentBuilder.value(XContentBuilder.java:772)
at org.elasticsearch.common.xcontent.XContentBuilder.field(XContentBuilder.java:764)
at org.elasticsearch.search.builder.SearchSourceBuilder.toXContent(SearchSourceBuilder.java:1184)
at org.elasticsearch.common.xcontent.XContentHelper.toXContent(XContentHelper.java:349)
at org.elasticsearch.search.builder.SearchSourceBuilder.toString(SearchSourceBuilder.java:1558)
at org.elasticsearch.search.builder.SearchSourceBuilder.toString(SearchSourceBuilder.java:1553)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at org.elasticsearch.action.search.SearchRequest.toString(SearchRequest.java:516)
从异常信息看,显然ES无法接受BigDecimal类型,经过百度,也确实如此。在一篇博文评论中解释如下:
应该是客户端代码里将查询的数值定义成了java.math.BigDecimal,而ES不支持这个类型。之所以2.2没有问题,是因为之前的transport client发送数据之前将其序列化成了json,而在5.x以后,使用的内部的transport protocol,数据类型如果不匹配会抛错误。
所以数据类型的定义上,需要使用ES支持的类型。
解决方案
方案一:转变成其他ES支持的数据类型
我使用的是6.4.2版本的Elasticsearch,该版本尚不支持BigDecimal或者BigInteger的数据类型,所以在index到Elasticsearch之前,需要转换成其他数据类型,这里要注意不要数据溢出了:
- BigDecimal要转变成Double类型
- BigInteger要转变成Long类型
方案二:使用更高版本的ES
我在看6.7.1版本的Elasticsearch源码时发现已经可以支持BigDecimal或者BigInteger的数据类型了,所以直接使用该版本或更高版本的就行了。
下面附上两个版本的支持的数据类型的源码:
- 6.4.2版本的Elasticsearch相关源码
Map<Class<?>, Writer> writers = new HashMap<>();
writers.put(Boolean.class, (b, v) -> b.value((Boolean) v));
writers.put(Byte.class, (b, v) -> b.value((Byte) v));
writers.put(byte[].class, (b, v) -> b.value((byte[]) v));
writers.put(Date.class, XContentBuilder::timeValue);
writers.put(Double.class, (b, v) -> b.value((Double) v));
writers.put(double[].class, (b, v) -> b.values((double[]) v));
writers.put(Float.class, (b, v) -> b.value((Float) v));
writers.put(float[].class, (b, v) -> b.values((float[]) v));
writers.put(Integer.class, (b, v) -> b.value((Integer) v));
writers.put(int[].class, (b, v) -> b.values((int[]) v));
writers.put(Long.class, (b, v) -> b.value((Long) v));
writers.put(long[].class, (b, v) -> b.values((long[]) v));
writers.put(Short.class, (b, v) -> b.value((Short) v));
writers.put(short[].class, (b, v) -> b.values((short[]) v));
writers.put(String.class, (b, v) -> b.value((String) v));
writers.put(String[].class, (b, v) -> b.values((String[]) v));
writers.put(Locale.class, (b, v) -> b.value(v.toString()));
writers.put(Class.class, (b, v) -> b.value(v.toString()));
writers.put(ZonedDateTime.class, (b, v) -> b.value(v.toString()));
writers.put(Calendar.class, XContentBuilder::timeValue);
writers.put(GregorianCalendar.class, XContentBuilder::timeValue);
- 6.7.1版本的Elasticsearch相关源码
Map<Class<?>, Writer> writers = new HashMap<>();
writers.put(Boolean.class, (b, v) -> b.value((Boolean) v));
writers.put(Byte.class, (b, v) -> b.value((Byte) v));
writers.put(byte[].class, (b, v) -> b.value((byte[]) v));
writers.put(Date.class, XContentBuilder::timeValue);
writers.put(Double.class, (b, v) -> b.value((Double) v));
writers.put(double[].class, (b, v) -> b.values((double[]) v));
writers.put(Float.class, (b, v) -> b.value((Float) v));
writers.put(float[].class, (b, v) -> b.values((float[]) v));
writers.put(Integer.class, (b, v) -> b.value((Integer) v));
writers.put(int[].class, (b, v) -> b.values((int[]) v));
writers.put(Long.class, (b, v) -> b.value((Long) v));
writers.put(long[].class, (b, v) -> b.values((long[]) v));
writers.put(Short.class, (b, v) -> b.value((Short) v));
writers.put(short[].class, (b, v) -> b.values((short[]) v));
writers.put(String.class, (b, v) -> b.value((String) v));
writers.put(String[].class, (b, v) -> b.values((String[]) v));
writers.put(Locale.class, (b, v) -> b.value(v.toString()));
writers.put(Class.class, (b, v) -> b.value(v.toString()));
writers.put(ZonedDateTime.class, (b, v) -> b.value(v.toString()));
writers.put(Calendar.class, XContentBuilder::timeValue);
writers.put(GregorianCalendar.class, XContentBuilder::timeValue);
writers.put(BigInteger.class, (b, v) -> b.value((BigInteger) v));
writers.put(BigDecimal.class, (b, v) -> b.value((BigDecimal) v));
可以发现,在6.7.1版本的源码里,多出了最后的两种数据类型的支持:BigInteger和BigDecimal。
参考链接
ELK系列(4) - Elasticsearch cannot write xcontent for unknown value of type class java.math.BigDecimal的更多相关文章
- ELK系列(1) - Elasticsearch + Logstash + Kibana + Log4j2快速入门与搭建用例
前言 最近公司分了个ELK相关的任务给我,在一边学习一边工作之余,总结下这些天来的学习历程和踩坑记录. 首先介绍下使用ELK的项目背景:在项目的数据库里有个表用来存储消息队列的消费日志,这些日志用于开 ...
- ELK系列(3) - Elasticsearch修改jvm参数
方法 Elasticsearch默认会配置1G的JVM堆的初始值和最大值,该jvm参数被配置在/config/jvm.options里: -Xms1g -Xmx1g 如果只是个人开发小项目,可以把参数 ...
- elk 系列:Elasticsearch 7.2 集群部署+TLS 加密+认证登陆
背景 2019年5月21日,Elastic官方发布消息: Elastic Stack 新版本6.8.0 和7.1.0的核心安全功能现免费提供. 这意味着用户现在能够对网络流量进行加密.创建和管理用户. ...
- ELK系列七:Elasticsearch的集群配置和监控以及在部署ELK中踩的坑
1.基本下载安装 #按照ELK系列一博客安装启动即可,没有大坑,注意一下权限即可 chmod -R 777 ./elasticsearch #此外没有java的,注意安装下JDK,我这次部署的环境是C ...
- ELK系列~log4-nxlog-Fluentd-elasticsearch写json数据需要注意的几点
经验与实践 前两篇文章里我们介绍了nxlog的日志收集和转发<ELK系列~Nxlog日志收集加转发(解决log4日志换行导致json转换失败问题)>,今天我们主要总结一下,在与log4和f ...
- ELK(Logstash+Elasticsearch+Kibana)的原理和详细搭建
一. Elastic Stack Elastic Stack是ELK的官方称呼,网址:https://www.elastic.co/cn/products ,其作用是“构建在开源基础之上, Elast ...
- ELK系列~Fluentd对大日志的处理过程~16K
Fluentd是一个日志收集工具,有输入端和输出端的概念,前者主要是日志的来源,你可以走多种来源方式,http,forward,tcp都可以,后者输出端主要指把日志进行持久化的过程,你可以直接把它持久 ...
- elk系列8之logstash+redis+es的架构来收集apache的日志【转】
preface logstash--> redis --> logstash --> es这套架构在讲究松耦合关系里面是最简单的,架构图如下: 解释下这个架构图的流程 首先前端log ...
- elk系列5之syslog的模块使用【转】
preface rsyslog是CentOs系统自带的的一个日志工具,那么我们就配置logstash来接受rsyslog的日志. logstash的syslog模块 linux-node2上操作log ...
随机推荐
- linux vsftpd 服务配置
vsftpd.conf配置如下: # Example config file /etc/vsftpd/vsftpd.conf # # The default compiled in settings ...
- UnityShader实例15:屏幕特效之Bloom
http://blog.csdn.net/u011047171/article/details/48522073 Bloom特效 概述 Bloom,又称“全屏泛光”,是游戏中 ...
- 编写dockerfile
参考:http://www.cnblogs.com/liuyansheng/p/6098470.html 一.dockerfile介绍: 是一种被Docker程序解释的脚本,Dockerfile由一条 ...
- POJ2513(字典树+图的连通性判断)
//用map映射TLE,字典树就AC了#include"cstdio" #include"set" using namespace std; ; ;//26个小 ...
- css画三角形
效果图: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- Django框架之第三篇模板语法
一.什么是模板? 只要是在html里面有模板语法就不是html文件了,这样的文件就叫做模板. 二.模板语法分类 一.模板语法之变量:语法为 {{ }}: 在 Django 模板中遍历复杂数据结构的关键 ...
- 使用struts2进行文件下载以及下载权限控制的例子
本测试有两个模块,一个是文件上上传,一个是文件下载,文件下载的时候会检查是否足有权限,如果没有,就会转发到登录页面,如果有权限,就会直接启动下载程序,给浏览器一个输出流. 下面直接上我的代码: 登录表 ...
- [Android Lint] xxx is not translated in xxx 的解决方法
CLEAN项目即可 转自BLOG http://blog.csdn.net/feng88724/article/details/8835664
- R:安装、导入各种包。
library和require都可以载入包,但二者存在区别. #在一个函数中,如果一个包不存在,执行到library将会停止执行,require则会继续执行.require将会根据包的存在与否返回tr ...
- 阶段2-新手上路\项目-移动物体监控系统\Sprint1-声音报警子系统开发\第1节-Sprint Backlog规划
根据之前的sprint1-声音报警子系统是相对比较大的一个需求,需要把它进一步细化,然后指定sprint Backlog product Backlog是整个产品的功能列表! sprint Backl ...