【elasticsearch】记录ES查询数据结果为空的问题(单个字搜索可以,词语搜索为空)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 【elasticsearch】记录ES查询数据结果为空的问题(单个字搜索可以,词语搜索为空)

一、基本环境

  • elasticsearch 版本:7.11.1
  • 客户端环境:kibana v7.11.1、Java8 应用程序模块。

其中 kibana 主要用于数据查询诊断和查阅日志,Java8 为主要的客户端,数据插入和查询都是由Java 实现的。

二、问题现象

共有三个部署环境,一个是开发环境、一个是测试环境、一个是正式环境。

前提:APP的首页搜索功能(搜索设备列表和搜索智能列表)在开发环境和正式环境一切正常。

测试人员在测试APP的首页搜索功能(搜索设备列表和搜索智能列表),发现搜索智能列表功能正常,而搜索设备时,无数据。

使用 kibana 里的开发工具查询时单个汉字可以搜索出设备列表,而使用词语去搜索设备时一直搜索不到任何数据。

查询数据命令:命令 索引/_search

下图中的命令是查询该索引下的所有数据

示例(根据某一字段查询)如下:

GET device-name-index/_search
{
  "query": {
    "bool": {
      "must": [
        {"term": {
          "deviceName": {
            "value": "开关"
          }
        }}
      ]
    }
  }
}

搜索“开”字可以把设备名称中带有“开”字的设备搜索出来,但是搜索“开关”词语时,设备名称中带有“开关”词语的设备结果为空(ES中实际上有数据)。

三、案例介绍

使用 elasticsearch 存储设备列表的主要信息,document 内的 field,基本上是 integer keywordes 自动创建的索引 device-name-index 如下:

查询 mapping 信息,命令如下:

GET device-name-index/_mapping

结果返回如下:

{
  "device-name-index" : {
    "mappings" : {
      "properties" : {
        "deviceId" : {
          "type" : "integer"
        },
        "deviceModel" : {
          "type" : "text"
        },
        "deviceName" : {
          "type" : "text"
        },
        "deviceType" : {
          "type" : "text"
        },
        "floorName" : {
          "type" : "text"
        },
        "id" : {
          "type" : "integer"
        },
        "roomName" : {
          "type" : "text"
        },
        "sn" : {
          "type" : "text"
        }
      }
    }
  }
}

而部署在开发环境里的 es 索引里的字段类型如下:

{
  "device-name-index" : {
    "mappings" : {
      "properties" : {
        "deviceId" : {
          "type" : "integer"
        },
        "deviceModel" : {
          "type" : "keyword"
        },
        "deviceName" : {
          "type" : "text",
          "fields" : {
            "ikmaxword" : {
              "type" : "text",
              "analyzer" : "ik_max_word"
            },
            "pinyin" : {
              "type" : "text",
              "analyzer" : "pinyin"
            }
          },
          "analyzer" : "standard"
        },
        "deviceType" : {
          "type" : "keyword"
        },
        "floorName" : {
          "type" : "keyword"
        },
        "roomName" : {
          "type" : "keyword"
        },
        "sn" : {
          "type" : "keyword"
        }
      }
    }
  }
}

以上字段,只需要关注 deviceName 即可。因为搜索是根据此字段检索数据的。

可以很清楚的看到 deviceName 字段使用了 ik分词器(ik_max_word)。

四、问题原因

按照 mapping 返回结果来看,部署在测试环境的字段 deviceName 没有添加 ik 分词器,而 es 采取的策略是,如果没有添加自定义的分词器,那么便会使用 es 默认的标准分词器分词,这就是导致单个字搜索时可以检索出数据,而使用词语检索数据时无数据的原因。

五、解决方案

命令如下:

DELETE device-name-index

第二步:重建索引

命令如下:

PUT device-name-index
{
  "mappings": {
    "properties": {
      "deviceId": {
        "type": "integer"
      },
      "deviceModel": {
        "type": "keyword"
      },
      "deviceName": {
        "type": "text",
        "fields": {
          "ikmaxword": {
            "type": "text",
            "analyzer": "ik_max_word"
          },
          "pinyin": {
            "type": "text",
            "analyzer": "pinyin"
          }
        },
        "analyzer": "standard"
      },
      "deviceType": {
        "type": "keyword"
      },
      "floorName": {
        "type": "keyword"
      },
      "roomName": {
        "type": "keyword"
      },
      "sn": {
        "type": "keyword"
      }
    }
  }
}

第三步:触发程序灌数据

在我的项目中只需要修改设备名称即可触发数据内容变更(全量删除并全量更新),再次在APP首页搜索设备名称,单个字和词语都可以检索出数据,问题搞定。

使用ik分词器后,查看分词结果情况,命令格式:

GET 索引/_doc/索引下某字段_id/_termvectors?fields=字段名称.ikmaxword

使用es默认的分词器查看分词结果情况,命令:

GET 索引/_doc/索引下某字段_id/_termvectors?fields=字段名称

示例如下:

GET device-name-index/_doc/cO-TNIMBWdpBXCOgNBnM/_termvectors?fields=deviceName.ikmaxword

六、总结

问题虽小,但一定要追溯源头,比如此次测试环境的不规范操作。后期如果有删除索引的操作,应该先手动建立索引后,再灌数据,而不是直接让其自动 mapping 建立索引,自动 mapping 建立的字段类型,可能不是我们期望的。

完结!


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
2月前
|
存储 自然语言处理 BI
|
3月前
|
数据可视化 Java Windows
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client
本文介绍了如何在Windows环境下安装Elasticsearch(ES)、Elasticsearch Head可视化插件和Kibana,以及如何配置ES的跨域问题,确保Kibana能够连接到ES集群,并提供了安装过程中可能遇到的问题及其解决方案。
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client
|
1天前
|
存储 人工智能 API
(Elasticsearch)使用阿里云 infererence API 及 semantic text 进行向量搜索
本文展示了如何使用阿里云 infererence API 及 semantic text 进行向量搜索。
|
1月前
|
存储 缓存 固态存储
Elasticsearch高性能搜索
【11月更文挑战第1天】
43 6
|
1月前
|
API 索引
Elasticsearch实时搜索
【11月更文挑战第2天】
40 1
|
2月前
|
人工智能
云端问道12期-构建基于Elasticsearch的企业级AI搜索应用陪跑班获奖名单公布啦!
云端问道12期-构建基于Elasticsearch的企业级AI搜索应用陪跑班获奖名单公布啦!
179 2
|
2月前
|
存储 JSON 监控
大数据-167 ELK Elasticsearch 详细介绍 特点 分片 查询
大数据-167 ELK Elasticsearch 详细介绍 特点 分片 查询
55 4
|
2月前
|
Web App开发 JavaScript Java
elasticsearch学习五:springboot整合 rest 操作elasticsearch的 实际案例操作,编写搜索的前后端,爬取京东数据到elasticsearch中。
这篇文章是关于如何使用Spring Boot整合Elasticsearch,并通过REST客户端操作Elasticsearch,实现一个简单的搜索前后端,以及如何爬取京东数据到Elasticsearch的案例教程。
221 0
elasticsearch学习五:springboot整合 rest 操作elasticsearch的 实际案例操作,编写搜索的前后端,爬取京东数据到elasticsearch中。
|
2月前
|
存储 JSON Java
elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。
这篇文章是关于Elasticsearch的学习指南,包括了解Elasticsearch、版本对应、安装运行Elasticsearch和Kibana、安装head插件和elasticsearch-ik分词器的步骤。
207 0
elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。
|
3月前
|
存储 缓存 自然语言处理
深度解析ElasticSearch:构建高效搜索与分析的基石
【9月更文挑战第8天】在数据爆炸的时代,如何快速、准确地从海量数据中检索出有价值的信息成为了企业面临的重要挑战。ElasticSearch,作为一款基于Lucene的开源分布式搜索和分析引擎,凭借其强大的实时搜索、分析和扩展能力,成为了众多企业的首选。本文将深入解析ElasticSearch的核心原理、架构设计及优化实践,帮助读者全面理解这一强大的工具。
244 7