如何使用ES更有效率的进行多字段模糊匹配

简介: 如何使用ES更有效率的进行多字段模糊匹配

背景


有时候需要ES模糊多个多个和中文相关的字段,可以把多个字段合成一个逻辑意义上的字段进行模糊


相关信息


此时需要两个配置:


1、copy_to (将多个字段整合成一个字段)官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/5.5/copy-to.html


2、ngram (分词器在对纯中文或者中英文混合相关等检索的时候很犀利,无脑的将词分隔成成为几个字连接起来)官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/5.5/analysis-ngram-tokenizer.html


如下示配置看,将first_name和last_name字段copy到一个字段full_name中


注意⚠️:(这个会不会产生一个情况?用户输入的前半段和后半段,命中了字段合在一起的中间部分,如A字段值:abc,B字段值为:def,把A、B字段合并后进行模糊分词匹配的时候会不会匹配中:cd这个值?)如果是使用copyto,不用担心这个。如果你使用的是binlog同步使用字符串拼接的方式产生的字段,会产生括号中所属的情况

PUT my_index
{
  "mappings": {
    "my_type": {
      "properties": {
        "first_name": {
          "type": "text",
          "copy_to": "full_name" 
        },
        "last_name": {
          "type": "text",
          "copy_to": "full_name" 
        },
        "full_name": {
          "type": "text"
        }
      }
    }
  }
}
PUT my_index/my_type/1
{
  "first_name": "John",
  "last_name": "Smith"
}
GET my_index/_search
{
  "query": {
    "match": {
      "full_name": { 
        "query": "John Smith",
        "operator": "and"
      }
    }
  }
}

试一下没有进行额外配置ngrem默认的分词效果:会为字符创建一个offset,更加方便命中数据

GET _analyze
{
  "tokenizer": "ngram",
  "text": "我的测试"
}
#产生的效果
{
  "tokens": [
    {
      "token": "我",
      "start_offset": 0,
      "end_offset": 1,
      "type": "word",
      "position": 0
    },
    {
      "token": "我的",
      "start_offset": 0,
      "end_offset": 2,
      "type": "word",
      "position": 1
    },
    {
      "token": "的",
      "start_offset": 1,
      "end_offset": 2,
      "type": "word",
      "position": 2
    },
    {
      "token": "的测",
      "start_offset": 1,
      "end_offset": 3,
      "type": "word",
      "position": 3
    },
    {
      "token": "测",
      "start_offset": 2,
      "end_offset": 3,
      "type": "word",
      "position": 4
    },
    {
      "token": "测试",
      "start_offset": 2,
      "end_offset": 4,
      "type": "word",
      "position": 5
    },
    {
      "token": "试",
      "start_offset": 3,
      "end_offset": 4,
      "type": "word",
      "position": 6
    }
  ]
}

进行ngrem配置

min_gram和max_gram 有助于分词的效率,类似一个窗口(如下配置像一个长度1~3单位的窗口,可以在字段字符上来回滑动分词),窗口长度拉的越长,匹配的更加具体,长度越小,匹配质量越低

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "ngram",
          "min_gram": 3,
          "max_gram": 3,
          "token_chars": [
            "letter",
            "digit"
          ]
        }
      }
    }
  }
}
POST my_index/_analyze
{
  "analyzer": "my_analyzer",
  "text": "2 Quick Foxes."
}

后续java示例伪代码

        int from = (pageNum - 1) * pageSize;
        SearchSourceBuilder builder = new SearchSourceBuilder();
    BoolQueryBuilder rootQuery = QueryBuilders.boolQuery();
    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    boolQueryBuilder.must(QueryBuilders.matchQuery("full_name", "模糊匹配的内容").operator(Operator.AND));
        rootQuery.filter(boolQueryBuilder);
        builder.setQuery(rootQuery);
        builder.from(from);
        builder.size(pageSize);
        SearchRequest searchRequest = new SearchRequest("indexName");
        searchRequest.source(builder);
        try {
            SearchResponse response = client.search(searchRequest);
            return response;
        } catch (IOException e) {
            throw new BaseException("es查询连接出错:" + e.getMessage());
        }catch (ElasticsearchException e){
            throw new BaseException("es查询出错:" + e.getMessage());
        }
相关文章
|
安全 数据安全/隐私保护 Windows
解锁安全之门,Windows Server 2019密码修改攻略大揭秘
解锁安全之门,Windows Server 2019密码修改攻略大揭秘
1596 0
|
SQL 关系型数据库 数据库
学习分布式事务Seata看这一篇就够了,建议收藏
学习分布式事务Seata看这一篇就够了,建议收藏
25809 2
|
11月前
|
SQL 监控 Java
SkyWalking10.2.0使用指南
最近使用SkyWalking 10.2.0发现发生了很多变化,现在介绍如下
1407 7
|
消息中间件 监控 Java
RocketMQ 同步发送、异步发送和单向发送,如何选择?
本文详细分析了 RocketMQ 中同步发送、异步发送和单向发送三种消息发送方式的原理、优缺点及适用场景。同步发送可靠性高但延迟较大,适合订单系统等场景;异步发送非阻塞且延迟低,适用于实时数据处理等场景;单向发送高效但可靠性低,适用于日志收集等场景。文章还提供了示例代码和核心源码分析,帮助读者更好地理解每种发送方式的特点。
2721 4
|
XML JSON API
如何在 Postman 中上传文件和 JSON 数据
如果你想在 Postman 中同时上传文件和 JSON 数据,本文将带你一步一步地了解整个过程,包括最佳实践和技巧,让你的工作更轻松。
|
NoSQL Java Redis
开发实战:使用Redisson实现分布式延时消息,订单30分钟关闭的另外一种实现!
本文详细介绍了 Redisson 延迟队列(DelayedQueue)的实现原理,包括基本使用、内部数据结构、基本流程、发送和获取延时消息以及初始化延时队列等内容。文章通过代码示例和流程图,逐步解析了延迟消息的发送、接收及处理机制,帮助读者深入了解 Redisson 延迟队列的工作原理。
|
开发框架 运维 供应链
如何进行资产梳理(上)
本文介绍了资产梳理的重要性,特别是对于蓝队成员在护网行动中的准备工作。资产梳理包括安全防护设备、对外开放服务项目和项目外包业务流程的详细信息整理,如设备型号、版本、责任人等。此外,还提到了两种资产梳理方式:一是关注业务资源、设备资产和第三方服务信息;二是识别和管理账号权限、互联网风险、后台目录风险、旁站风险、C段风险和端口风险。文章强调了暴露面收敛的重要性,如关闭非必要服务和端口,以降低安全风险。最后,作者总结了资产梳理的步骤,认为这与Web信息收集类似,是蓝队防御的关键环节。
2538 6
|
消息中间件 Java RocketMQ
Spring Boot与RocketMQ的集成
Spring Boot与RocketMQ的集成
|
消息中间件 监控 安全
Kafka客户端工具:Offset Explorer 使用指南
Kafka客户端工具:Offset Explorer 使用指南
15140 0