elasticsearch初体验,踩坑

背景

在开发一个新的需求的过程中,涉及到有些查询量大,频次高,搜索条件复杂,所以会将数据存到elasticsearch中,一方面可以提高性能,另外减小数据库的压力。

业务逻辑

在创建一个业务单据的时候,会同时在数据库和es集群中插入数据,数据接口基本一致,业务操作不外乎增删改查,索引按月分,工程-表-yyyyMM的方式命名,索引新增记录的时候自动创建。

踩坑过程

  • 代码写完了就进行单元测试,首先创建数据,一条OK,检查数据库、es都没问题;然后一次创建多条。继续检查数据库、es没问题,心里感觉稳了一半。
  • 然后执行搜索逻辑,一开始es索引计算出了点小问题,不大,很快弄好;首先不带条件查询一次,每页10条,结果ok,正常,感觉自己的代码写的很稳,心情愉快。
  • 一切的噩梦从此开始,查询条件有个时间范围搜索,这种情况,肯定挑最复杂的测试了,赶紧设置一个本月第一天到最后一天最后一秒的范围,这绝对能覆盖到数据了。运行之后,诶,怎么查不到数据,一定是我姿势不对,再来亿遍,还是不行!!!。
  • 赶紧看下es查询语句是啥,断点到下面的语句,
SearchResponse searchResponse = requestBuilder.get();
  • 然后debug模式下的值计算看一下requestBuilder.toString()是什么情况,es查询语句如下,目测毫无问题,
{
  "from" : 0,
  "size" : 10,
  "post_filter" : {
    "range" : {
      "createTime" : {
        "from" : "2020-03-01 00:00:00",
        "to" : "2020-03-30 23:59:59",
        "include_lower" : true,
        "include_upper" : true
      }
    }
  },
  "sort" : [ {
    "createTime" : {
      "order" : "desc"
    }
  } ]
}
  • 将语句放到elasticsearch-head中查看一下,竟然真的查不到数据。这个时候感觉不是代码问题了,是es的哪里配置的问题。
  • 首先去看下其他地方使用es的方式,发现java代码大同小异,都是使用api进行调用,先排除一下代码问题。
  • 考虑到加上搜索条件有问题,去掉搜索条件就没问题,考虑是不是这个字段的问题,然后查询了一下其他的精确查找的字段(比如:id),发现也没问题。
  • 然后删掉这个索引,将date类型使用timstamp 时间戳的方式存储,然后搜索条件中就不是时间格式而是数字了, 再次查询,查询条件也处理成long数字,搜索条件正常生效,现在看来是date类型字符串没法查,但是不能就这样改成long类型保存,不利于查看数据。
  • 查了下文档,突然想起来es会存在分词搜索的问题,所以赶紧确认下字段的分词效果,elasticsearch-head可以直接查看索引详情,方便,果然 createTime 只有type是string,默认是会分词的,
"mappings": {
    "test-type": {
      "properties": {
        "createTime": {
          "type": "string"
        }
}
  • 至此找到了问题点,赶紧去创建一波mapping,把所有的字段一个个type,index全部配置好, 然后通过api创建mapping,结果竟然失败了,提示: orderType int 不能转为string, 赶紧检查了一下mappings,发现也确实没写错
  • 猜想是不是已经有这个index的问题无法创建了,所以先删除index再创建一次,还是报类似的错误。
  • 接下来elasticsearch-head上查看索引信息,发现总是会存在了一个其他的mappings,名字为product,然后有部分字段与我现在要增加的订单中字段相同,但是全部用的string,这个时候基本猜到是因为同一索引,不同type字段类型必须相同导致的。
  • 重新创建一个新的索引,把名字加长一点,原来是比如: project-biz-202003 现在改成 project-biz-abc-202003,这样就是不同索引了,再次创建mappings,卧槽,竟然还报错,然后新增一条数据看下,再去检查索引详情,真是怪了,product又出现了,阴魂不散啊。
  • 到此我已经花了3个小时了,我都快怀疑自己了,上个厕所路上就想是不是在哪里配置了一个规则会自动创建product这个mapping,然后就去公司的在线文档去搜索,搜了很多页,终于发现一个地址:[http://ip:9200/_plugin/kopf/#!/cluster],这比elasticsearch-head好用多了,然后一路找里面的功能,找到了这个:
    image.png
  • 终于发现问题了,原来很早以前有人创建了一个project-biz-*的索引模板,只要是符合在规则的索引都会创建一个该模板配置的mappings。
  • 找到原因就好弄了,重新将新的业务es所以命名为与之不匹配的名字,比如project-business-table-*,将mappings配置加进去,完成。
  • 测试一下,新增-查询-带参查询-范围查询全部ok了,至此坑踩完了。

结论

  1. 首先使用es前基本的操作要熟悉,比如查询语句怎么写,会查文档。
  2. 存储新的数据到es,要提前创建mappings,设置好每个字段分词策略
  3. 创建index template的时候 template的命名最好不要太大的匹配,如果有人以公司名开头的xx-* ,那后来的人就很麻烦了,所有的索引都会匹配上这个规则,所以 最好是 [工程名-业务-表-*]的方式,这样每个template就不会被有冲突了。
    image.png
  4. 这次的坑其实不应该踩的,问了几个同事竟然都不知道有这个mappings,说明公司在这方面没没有好好的沉淀,文档上面都只有一个后台地址,并没有告诉具体要做什么,所以我新加了一个文档说明,给后来的同事参考。

你可能感兴趣的:(elasticsearch初体验,踩坑)