ElasticSearch查询学习笔记章节2——prefix,fuzzy,wildcard,range,regexp查询

ElasticSearch查询笔记目录

  涉及的常用查询内容较多,将分多个章节进行笔记整理,具体如下:

  1. ElasticSearch查询学习笔记章节1——term,terms,match,id查询

   主要是依据精准的查询条件来查询,查询速度快,也是最常用的几类查询方式,具体种类如下:

  • term查询
  • terms查询
  • match_all查询
  • match查询
  • 布尔match查询
  • multi_match查询
  • 根据文档id查询(单个id)
  • 根据文档ids查询(多个id)
  1. ElasticSearch查询学习笔记章节2——prefix,fuzzy,wildcard,range,regexp查询

  主要是涉及ElasticSearch查询条件相对模糊,查询速度相对慢,实时查询时应尽量避免这些方式,但是这些查询方式又具有自己独特不可代替的功能,还是还有必要,具体如下:

  • prefix查询
  • fuzzy查询
  • wildcard查询
  • range查询
  • regexp查询
  1. ElasticSearch查询学习笔记章节3——scroll,delete-by-query,bool,boosting,filter,highlight查询

  主要涉及ElasticSearch的一些常用的杂项查询;

  • 深分页scroll查询
  • delete-by-query
  • bool查询
  • boosting查询
  • filter查询
  • highlight(高亮)查询
  1. ElasticSearch查询学习笔记章节4——cardinality,range,extended_stats聚合统计aggregations查询

  主要涉及ES的聚合查询Aggregations;

  • cardinality(去重计数)查询
  • range(范围统计)查询
  • extended_stats(统计聚合)查询
  1. ElasticSearch查询学习笔记章节5——geo_distance,geo_bounding_box,geo_polygon地图检索geo查询

.   主要涉及ES的地图检索geo相关的查询;

  • geo_distance查询
  • geo_bounding_box查询
  • geo_polygon查询

整体Java代码的测试用例项目

  整个章节的Java代码放在CSDN资源ElasticSearch常用查询的Java实现;路径效果如下图,欢迎下载访问;在这里插入图片描述

prefix查询

前缀查询,可以通过一个关键字 去指定一个field的前缀,从而查询到指定的文档

  实现要求,查询公司corpName字段查以上海开头的文档。

  注意:这里要和match查询区分开来,因为我们定义的公司corpName字段是keyword类型,所以单独的上海并不在分词库中,所以用match查询根本查不到单纯的以上海开头的公司。,但是prefix机制是可以的。

  RESTFUL代码如下;

#prefix前缀查询
POST /sms-logs-index/_search
{
  "query": {
    "prefix": {
      "corpName": {
        "value": "上海"
      }
    }
  }
}

  Java代码如下;

    static RestHighLevelClient myClient= EsClient.getClient();  //获取操作ES的
    String index="sms-logs-index";

    @Test
    public void findByPrefix() throws IOException {
        //1。创建request对象,查询用的对象一般都是SearchRequest对象
        SearchRequest request = new SearchRequest(index);

        //2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
        SearchSourceBuilder builder = new SearchSourceBuilder();

        //查询代码一般只要修改这一块
        //--------------------------------------------------------------------
        builder.query(QueryBuilders.prefixQuery("corpName","上海"));
        //--------------------------------------------------------------------

        builder.size(20);   //ES默认只查询10条记录,即默认size=10,如果需要查询更多,则需要加到size的值
        request.source(builder);

        //3. 执行查询
        SearchResponse response = myClient.search(request, RequestOptions.DEFAULT);

        //4. 获取到_source中的数据,并展示
        //遍历输出每个文档
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
        //输出总文档数
        System.out.println(response.getHits().getHits().length);
    }


fuzzy查询

模糊查询,我们输入字符的大概,ES就可以根据输入的内容去大概匹配一下结果,同时也支持输入关键字的错别字,所以fuzzy查询本身相对不太精确和稳定,即错别字太多也可能导致查询无结果,需要则中使用。
不同于MySQL的like查询,比Like查询要强大。

  实现要求,根据corpName字段模糊匹配公司名称。我们的ES库里面有个中威集团,这里我们通过输入中文集团,也能匹配到想要的效果。

fuzzy查询会用到两个很重要的参数,fuzziness,prefix_length
fuzziness:表示输入的关键字通过几次操作可以转变成为ES库里面的对应field的字段,操作是指:新增一个字符,删除一个字符,修改一个字符,每次操作可以记做编辑距离为1,如中文集团中威集团编辑距离就是1,只需要修改一个字符;该参数默认值为0,即不开启模糊查询,一样的,如果fuzziness值在这里设置成2,会把编辑距离为2的东东集团也抓出来。
prefix_length:表示限制输入关键字和ES对应查询field的内容开头的第n个字符必须完全匹配,不允许错别字匹配,如这里等于1,则表示开头的字必须匹配,不匹配则不返回,默认值也是0,加大prefix_length的值可以提高效率和准确率。
注意:这两个参数不是只适用于fuzzy查询,match查询一样适用,后续将es的参数优化我们会细讲,这里简单说明下,会使用即可。

  RESTFUL代码如下;

# fuzzy查询1
GET /sms-logs-index/_search
{
  "query": {
    "fuzzy": {
      "corpName": {
        "value": "中文集团"
        ,"fuzziness":1
        ,"prefix_length": 1
      
      }
    }
  }
}

#fuzzy查询2 允许编辑两次距离
GET /sms-logs-index/_search
{
  "query": {
    "fuzzy": {
      "corpName": {
        "value": "中文集团"
        ,"fuzziness":2
      
      }
    }
  }
}

Kibana查询结果如下

# fuzzy查询1
# GET /sms-logs-index/_search
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.9029796,
    "hits" : [
      {
        "_index" : "sms-logs-index",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 0.9029796,
        "_source" : {
          "createDate" : "2020-09-16",
          "senDate" : "2020-09-16",
          "longCode" : "5478434123",
          "moblie" : 18056587445,
          "corpName" : "中威集团",
          "smsContent" : "中威集团,服务于你的身边!",
          "state" : "0",
          "opratorId" : "3",
          "province" : "杭州",
          "ipAddr" : "10.248.19.45",
          "replyTotal" : "4",
          "fee" : "20"
        }
      }
    ]
  }
}

#fuzzy查询2 允许编辑两次距离,东东集团也可以匹配到
# GET /sms-logs-index/_search
{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.9029796,
    "hits" : [
      {
        "_index" : "sms-logs-index",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 0.9029796,
        "_source" : {
          "createDate" : "2020-09-16",
          "senDate" : "2020-09-16",
          "longCode" : "5478434123",
          "moblie" : 18056587445,
          "corpName" : "中威集团",
          "smsContent" : "中威集团,服务于你的身边!",
          "state" : "0",
          "opratorId" : "3",
          "province" : "杭州",
          "ipAddr" : "10.248.19.45",
          "replyTotal" : "4",
          "fee" : "20"
        }
      },
      {
        "_index" : "sms-logs-index",
        "_type" : "_doc",
        "_id" : "5",
        "_score" : 0.6019864,
        "_source" : {
          "createDate" : "2020-09-16",
          "senDate" : "2020-09-16",
          "longCode" : "24514635",
          "moblie" : 18545427895,
          "corpName" : "东东集团",
          "smsContent" : "数据驱动,AI推动,新零售模型让你的购买更心怡!",
          "state" : "1",
          "opratorId" : "1",
          "province" : "北京",
          "ipAddr" : "10.254.19.45",
          "replyTotal" : "1",
          "fee" : "6000"
        }
      }
    ]
  }
}

  Java代码如下;

    static RestHighLevelClient myClient= EsClient.getClient();  //获取操作ES的
    String index="sms-logs-index";
    
    @Test
    public void findByFuzzy() throws IOException {
        //1。创建request对象,查询用的对象一般都是SearchRequest对象
        SearchRequest request = new SearchRequest(index);

        //2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
        SearchSourceBuilder builder = new SearchSourceBuilder();

        //查询代码一般只要修改这一块
        //--------------------------------------------------------------------
        builder.query(QueryBuilders.fuzzyQuery("corpName","中文集团").prefixLength(0).fuzziness(Fuzziness.TWO));
        //--------------------------------------------------------------------

        builder.size(20);   //ES默认只查询10条记录,即默认size=10,如果需要查询更多,则需要加到size的值
        request.source(builder);

        //3. 执行查询
        SearchResponse response = myClient.search(request, RequestOptions.DEFAULT);

        //4. 获取到_source中的数据,并展示
        //遍历输出每个文档
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
        //输出总文档数
        System.out.println(response.getHits().getHits().length);
    }

  Java代码测试结果如下图;

在这里插入图片描述

图1 fuzzy查询java测试代码结果

wildcard查询

通配查询,和MySQL中的like是一个套路,可以在查询时,在字符串中指定通配符*和占位符?

  实现要求,依据corpName字段查询查询以集团结尾的公司或者某某集团为公司名的记录(某某只限两个字)

  RESTFUL代码如下;

# wildcard 查询 利用*做通配符
POST /sms-logs-index/_search
{
  "query": {
    "wildcard": {
      "corpName": {
        "value": "*集团"
      }
    }
  }
}

# wildcard 查询 利用?做占位符
POST /sms-logs-index/_search
{
  "query": {
    "wildcard": {
      "corpName": {
        "value": "??集团"
      }
    }
  }
}

  Java代码如下;

    static RestHighLevelClient myClient= EsClient.getClient();  //获取操作ES的
    String index="sms-logs-index";

    @Test
    public void findByWildCard() throws IOException {
        //1。创建request对象,查询用的对象一般都是SearchRequest对象
        SearchRequest request = new SearchRequest(index);

        //2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
        SearchSourceBuilder builder = new SearchSourceBuilder();

        //查询代码一般只要修改这一块
        //--------------------------------------------------------------------
        builder.query(QueryBuilders.wildcardQuery("corpName","*集团"));
        //--------------------------------------------------------------------

        builder.size(20);   //ES默认只查询10条记录,即默认size=10,如果需要查询更多,则需要加到size的值
        request.source(builder);

        //3. 执行查询
        SearchResponse response = myClient.search(request, RequestOptions.DEFAULT);

        //4. 获取到_source中的数据,并展示
        //遍历输出每个文档
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
        //输出总文档数
        System.out.println(response.getHits().getHits().length);
    }

  Java代码测试结果如下图;
在这里插入图片描述

图2 wildcard查询java测试代码结果

range查询

范围查询,只针对数值类型(字符类型则不适用),对某一个field进行大于或者小于的范围查询。

  实现要求,依据fee字段查询所有消费大于等于100,小于等于500的公司。

  RESTFUL代码如下;

# range查询
POST /sms-logs-index/_search
{
  "query": {
    "range": {
      "fee": {
        "gte": 100,
        "lte": 500
      }
    }
  }
}

gt 大于
gte 大于等于
lt 小于
lte 小于等于

  Java代码如下;

    static RestHighLevelClient myClient= EsClient.getClient();  //获取操作ES的
    String index="sms-logs-index";

    @Test
    public void findByRange() throws IOException {
        //1。创建request对象,查询用的对象一般都是SearchRequest对象
        SearchRequest request = new SearchRequest(index);

        //2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
        SearchSourceBuilder builder = new SearchSourceBuilder();

        //查询代码一般只要修改这一块
        //--------------------------------------------------------------------
        builder.query(QueryBuilders.rangeQuery("fee").gte(100).lte(500));
        //--------------------------------------------------------------------

        builder.size(20);   //ES默认只查询10条记录,即默认size=10,如果需要查询更多,则需要加到size的值
        request.source(builder);

        //3. 执行查询
        SearchResponse response = myClient.search(request, RequestOptions.DEFAULT);

        //4. 获取到_source中的数据,并展示
        //遍历输出每个文档
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
        //输出总文档数
        System.out.println(response.getHits().getHits().length);
    }


regexp查询

正则表达式查询,通过编写的正则表达式进行内容匹配
注意:prefix,fuzzy,wildcard,regexp查询相对都是精确的条件,查询效率也是相抵较低,业务要求实时性高的场景,应该避免使用。

  实现要求,依据moblie字段查询查询13手机号开头的公司信息。

  RESTFUL代码如下;

# regexp查询
POST /sms-logs-index/_search
{
  "query": {
    "regexp": {
      "moblie": "13[0-9]{9}"
    }
  }
}


  Java代码如下;

    static RestHighLevelClient myClient= EsClient.getClient();  //获取操作ES的
    String index="sms-logs-index";

    @Test
    public void findByRegexp() throws IOException {
        //1。创建request对象,查询用的对象一般都是SearchRequest对象
        SearchRequest request = new SearchRequest(index);

        //2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
        SearchSourceBuilder builder = new SearchSourceBuilder();

        //查询代码一般只要修改这一块
        //--------------------------------------------------------------------
        builder.query(QueryBuilders.regexpQuery("moblie","13[0-9]{9}"));
        //--------------------------------------------------------------------

        builder.size(20);   //ES默认只查询10条记录,即默认size=10,如果需要查询更多,则需要加到size的值
        request.source(builder);

        //3. 执行查询
        SearchResponse response = myClient.search(request, RequestOptions.DEFAULT);

        //4. 获取到_source中的数据,并展示
        //遍历输出每个文档
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
        //输出总文档数
        System.out.println(response.getHits().getHits().length);
    }
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

╭⌒若隐_RowYet——大数据

谢谢小哥哥,小姐姐的巨款

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值