前言

目前正在出一个Es专题系列教程, 篇幅会较多, 喜爱的话,给个重视❤️ ~

承接上文,本节给咱们讲下上节留传的查询操作以及要点内容分词原理~

为了方便学习, 本节中所有示例沿用上节的索引。本文偏实战一些,好了, 废话不多说直接开整吧~

另外: 之前不少小伙伴私信,说老干讲,没有结合java代码去演示,这里了解咱们火急想要敲代码的心境,期望快速的在项目顶用起来。我在学习一个新东西,特别是这种中间件的运用,我会先抛开代码层面,从它底子上去认识它,知道这个进程是怎么样的,因为封装好的sdk,其实也都是对接口进行了封装,方便开发人员去运用, 写代码咱们都会写,关键是如何去了解一个东西。就像面试一样,咱们都会背,可是纷歧定都答的好

透露一下,后边会有专门几节讲springboot整合es的实战内容,只要不忙,正常更新教程~

prefix & wildcard & regexp

上节咱们讲的查询操作,其最小单位都是依据词条进行查询。有时候,咱们需求将查询的最小粒度优化到字符级别。很明显中文是不会依据空格分词的,这个时候咱们就需求用到部分匹配查询prefix、wildcard、regexp

其实这个查询咱们能够类比成含糊查询

prefix & 前缀查询

POST class_1/_search
{
  "query": {
    "prefix": {
      "name": {
        "value": "i"
      }
    }
  }
}

回来:

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "imFt-4UBECmbBdQAnVJg",
        "_score" : 1.0,
        "_source" : {
          "name" : "i",
          "age" : 10
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "b8fcCoYB090miyjed7YE",
        "_score" : 1.0,
        "_source" : {
          "name" : "I eat apple so haochi1~",
          "num" : 1
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "ccfcCoYB090miyjed7YE",
        "_score" : 1.0,
        "_source" : {
          "name" : "I eat apple so haochi3~",
          "num" : 1
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "cMfcCoYB090miyjed7YE",
        "_score" : 1.0,
        "_source" : {
          "name" : "I eat apple so zhen haochi2~",
          "num" : 1
        }
      }
    ]
  }
}

wildcard 通配查询

意思能够指定通配符,比方*

POST class_1/_search
{
  "query": {
    "wildcard": {
      "name": {
        "value": "*a*"
      }
    }
  }
}

回来:

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "b8fcCoYB090miyjed7YE",
        "_score" : 1.0,
        "_source" : {
          "name" : "I eat apple so haochi1~",
          "num" : 1
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "ccfcCoYB090miyjed7YE",
        "_score" : 1.0,
        "_source" : {
          "name" : "I eat apple so haochi3~",
          "num" : 1
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "cMfcCoYB090miyjed7YE",
        "_score" : 1.0,
        "_source" : {
          "name" : "I eat apple so zhen haochi2~",
          "num" : 1
        }
      }
    ]
  }
}

regexp & 正则表达式查询

咱们能够经过regexp进行正则匹配

POST class_1/_search
{
  "query": {
    "regexp": {
      "name": {
        "value": "[A-Za-z0-9]*"
      }
    }
  }
}

回来:

{
  "took" : 8,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 10,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "h2Fg-4UBECmbBdQA6VLg",
        "_score" : 1.0,
        "_source" : {
          "name" : "b",
          "num" : 6
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "iGFt-4UBECmbBdQAnVJe",
        "_score" : 1.0,
        "_source" : {
          "name" : "g",
          "age" : 8
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "iWFt-4UBECmbBdQAnVJg",
        "_score" : 1.0,
        "_source" : {
          "name" : "h",
          "age" : 9
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "imFt-4UBECmbBdQAnVJg",
        "_score" : 1.0,
        "_source" : {
          "name" : "i",
          "age" : 10
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "num" : 9,
          "name" : "e",
          "age" : 9,
          "desc" : [
            "hhhh"
          ]
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 1.0,
        "_source" : {
          "name" : "f",
          "age" : 10,
          "num" : 10
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "b8fcCoYB090miyjed7YE",
        "_score" : 1.0,
        "_source" : {
          "name" : "I eat apple so haochi1~",
          "num" : 1
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "ccfcCoYB090miyjed7YE",
        "_score" : 1.0,
        "_source" : {
          "name" : "I eat apple so haochi3~",
          "num" : 1
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "l",
          "num" : 6
        }
      },
      {
        "_index" : "class_1",
        "_type" : "_doc",
        "_id" : "cMfcCoYB090miyjed7YE",
        "_score" : 1.0,
        "_source" : {
          "name" : "I eat apple so zhen haochi2~",
          "num" : 1
        }
      }
    ]
  }
}

ES中的分词

什么是分词

关于非结构语言的查询,假如采用全文检索的方法进行查询,需求进行对其进行分词处理, 顾名思义,将一句话或一大段话,经过必定的规矩,分割成多个词条的进程

分词器

es中的分词经过分词器来处理,主要由以下组成:

  • Character Filters:针对原始文本处理,比方去除一些标签,标点符号等。一个分词器中能够包含0至多个Character Filters
  • Tokenizer:依照规矩将原始文本切分为词条,比方依照空格切分。一个分词器中有且只有一个Tokenizer
  • Token Filters:将切分的单词进行加工,比方大写转小写删除结语词增加同义语。一个分词器中能够包含0至多个Token Filters

举个例子,假如有这么一句话I eat a apple <emoj>开心</emoj>,经过上述分词流程大致为:

  1. 开始分词, Character Filters开始对原始句子处理,处理完之后的句子: I eat a apple
  2. Tokenizer依据规矩分词,处理完之后的句子会分为几个词条 I, eat, a, apple
  3. Token Filters词条过滤处理, i, eat, a, apple

当然,不同分词器或许处理的会更复杂

内置分词器

  • Standard Analyzer :默认分词器,按词切分,小写处理
  • Simple Analyzer:依照非字母切分(符号被过滤),小写处理
  • Stop Analyzer:小写处理,停用词过滤(the ,a,is)
  • Whitespace Analyzer:依照空格切分,不转小写
  • Keyword Analyzer:不分词,直接将输入作为输出
  • Pattern Analyzer:正则表达式,默认 \W+
  • Language:供给了 30 多种常见语言的分词器
  • Customer Analyzer:自定义分词器

elasticsearch-analysis-ik & 中文分词器

通常咱们的事务,在大部分运用场景中都是中文,所以比较常用的就是中文分词器,默认是不带的,所以需求咱们去装置,这里就不多介绍装置了,文档里有

  • 地址-https://github.com/medcl/elasticsearch-analysis-ik

结束语

本节就到此结束了,下节咱们进入ES聚合部分内容,这部分内容也比较重要 ~

本着把自己知道的都告知咱们,假如本文对您有所协助,点赞+重视鼓励一下呗~

相关文章

  • 利用docker建立es集群
  • 一起来学ElasticSearch(一)
  • 一起来学ElasticSearch(二)
  • 一起来学ElasticSearch(三)
  • 一起来学ElasticSearch(四)
  • 一起来学ElasticSearch(五)
  • 一起来学ElasticSearch(六)
  • 一起来学ElasticSearch(七)

项目源码(源码已更新 欢迎star⭐️)

  • spring-cloud-all

  • SpringCloud整合 Oauth2+Gateway+Jwt+Nacos 完成授权码形式的服务认证(一)

  • SpringCloud整合 Oauth2+Gateway+Jwt+Nacos 完成授权码形式的服务认证(二)

往期并发编程内容引荐

  • Java多线程专题之线程与进程概述
  • Java多线程专题之线程类和接口入门
  • Java多线程专题之进阶学习Thread(含源码剖析)
  • Java多线程专题之Callable、Future与FutureTask(含源码剖析)
  • 面试官: 有了解过线程组和线程优先级吗
  • 面试官: 说一下线程的生命周期进程
  • 面试官: 说一下线程间的通信
  • 面试官: 说一下Java的同享内存模型
  • 面试官: 有了解过指令重排吗,什么是happens-before
  • 面试官: 有了解过volatile关键字吗 说说看
  • 面试官: 有了解过Synchronized吗 说说看
  • Java多线程专题之Lock锁的运用
  • 面试官: 有了解过ReentrantLock的底层完成吗?说说看
  • 面试官: 有了解过CAS和原子操作吗?说说看
  • Java多线程专题之线程池的基本运用
  • 面试官: 有了解过线程池的工作原理吗?说说看
  • 面试官: 线程池是如何做到线程复用的?有了解过吗,说说看
  • 面试官: 堵塞行列有了解过吗?说说看
  • 面试官: 堵塞行列的底层完成有了解过吗? 说说看
  • 面试官: 同步容器和并发容器有用过吗? 说说看
  • 面试官: CopyOnWrite容器有了解过吗? 说说看
  • 面试官: Semaphore在项目中有运用过吗?说说看(源码剖析)
  • 面试官: Exchanger在项目中有运用过吗?说说看(源码剖析)
  • 面试官: CountDownLatch有了解过吗?说说看(源码剖析)
  • 面试官: CyclicBarrier有了解过吗?说说看(源码剖析)
  • 面试官: Phaser有了解过吗?说说看
  • 面试官: Fork/Join 有了解过吗?说说看(含源码剖析)
  • 面试官: Stream并行流有了解过吗?说说看

博客(阅览体会较佳)

  • 我的博客(阅览体会较佳)

  • 地址: github.com/qiuChenglei…

引荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)

  • springboot-all

  • 地址: github.com/qiuChenglei…

  • SpringBoot系列教程合集

  • 一起来学SpringCloud合集