Elasticsearch进阶(倒排索引、高级查询_DSL语言查询与过滤、中文分词IK插件、文档映射)

1、ES9300端口号与9200区别

9300端口:ES节点之间通讯使用,是tcp协议端口号
9200端口:ES节点和外部通讯使用,暴露ES RESTful接口端口号

2、Elasticsearch倒排索引原理

全文检索检索底层采用排索 为什么?
倒排索引比数据库中B-tree树查询效率还要快?
倒排索引会对文档内容进行关键词分词,可以使用关键次直接定位到文档内容。

正向索引
正排表是以文档的ID为关键字,表中记录文档中每个字的位置信息,查找时扫描表中每个文档中字的信息直到找出所有包含查询关键字的文档。
这种组织方法在建立索引的时候结构比较简单,建立比较方便且易于维护;因为索引是基于文档建立的,若是有新的文档加入,直接为该文档建立一个新的索引块,挂接在原来索引文件的后面。若是有文档删除,则直接找到该文档号文档对应的索引信息,将其直接删除。但是在查询的时候需对所有的文档进行扫描以确保没有遗漏,这样就使得检索时间大大延长,检索效率低下。
尽管正排表的工作原理非常的简单,但是由于其检索效率太低,除非在特定情况下,否则实用性价值不大。

倒排索引
倒排表以字或词为关键字进行索引,表中关键字所对应的记录表项记录了出现这个字或词的所有文档,一个表项就是一个字表段,它记录该文档的ID和字符在该文档中出现的位置情况。
由于每个字或词对应的文档数量在动态变化,所以倒排表的建立和维护都较为复杂,但是在查询的时候由于可以一次得到查询关键字所对应的所有文档,所以效率高于正排表。在全文检索中,检索的快速响应是一个最为关键的性能,而索引建立由于在后台进行,尽管效率相对低一些,但不会影响整个搜索引擎的效率。

正排索引是从文档到关键字的映射(已知文档求关键字),倒排索引是从关键字到文档的映射(已知关键字求文档)。

文档内容:
在这里插入图片描述

3、Elasticsearch高级查询

根据id进行查询

GET /myindex/user/12

查询当前所有类型的文档

GET /myindex/user/_search

根据多个ID批量查询
查询多个id分别为1、2

GET /myindex/user/_mget
{
      "ids":["1","2"]
}

复杂条件查询
查询年龄为年龄21岁

GET /myindex/user/_search?q=age:21

查询年龄30岁-60岁之间

GET /myindex/user/_search?q=age[30 TO 60]
注意:TO 一定要大写

查询年龄30岁-60岁之间 并且年龄降序、从0条数据到第1条数据

GET /myindex/user/_search?q=age[30 TO 60]&sort=age:desc&from=0&size=1

查询年龄30岁-60岁之间 并且年龄降序、从0条数据到第1条数据,展示name和age字段

GET /myindex/user/_search?q=age[30 TO 60]&sort=age:desc&from=0&size=1
&_source=name,age

DSL语言查询与过滤
什么是DSL语言?
es中的查询请求有两种方式,一种是简易版的查询
另外一种是使用JSON完整的请求体,叫做结构化查询(DSL)
由于DSL查询更为直观也更为简易,所以大都使用这种方式。
DSL查询是POST过去一个json,由于post的请求是json格式的,所以存在很多灵活性,也有很多形式。

根据名称精确查询姓名

GET myindex/user/_search
{
  "query": {
    "term": {
      "name": "xiaoming"
    }
    
  }
  
}

注:term是代表完全匹配,即不进行分词器分析,文档中必须包含整个搜索的词汇

根据汽车名称模糊查询

GET /myindex/user/_search
{
  "from": 0,
  "size": 2, 
  "query": {
    "match": {
      
        "car": "奥迪"
      }
  }
}

注:match查询相当于模糊匹配,只包含其中一部分关键词就行

Term与Match区别
Term查询不会对字段进行分词查询,会采用精确匹配。
Match会根据该字段的分词器,进行分词查询。

使用filter过滤年龄

GET /myindex/user/_search
{
	"query": {
		"bool": {
			"must": [{
				"match_all": {}
			}],
			"filter": {
				"range": {
					"age": {
						"gt": 21,
						"lte": 51
					}
				}

			}

		}

	},
	"from": 0,
	"size": 10,
	"_source": ["name", "age"]

}
4、ElasticsearchlK分词器原理

链接:IK分词器原理

5、ElasticsearchlK中文分词器

因为Elasticsearch中默认的标准分词器分词器对中文分词不是很友好,会将中文词语拆分成一个一个中文的汉子。因此引入中文分词器-es-ik插件。

下载地址: https://github.com/medcl/elasticsearch-analysis-ik/releases
注意: es-ik分词插件版本一定要和es安装的版本对应
第一步:下载es的对应版本的IK插件命名改为ik
第二步: 上传到/usr/local/elasticsearch-6.4.3/plugins
第三步: 重启elasticsearch即可

使用standard标准分词器演示:
在这里插入图片描述

使用ik分词器后演示:
TODO


6、IK自定义中文词典热词
  • 我们知道standard标准分词器会将中文按照每个字分词,如"王者荣耀" 拆分为"王"、“者”、“荣”、“耀”。
  • 而使用了IK分词器后,“王者荣耀” 拆分为"王者"、“荣耀”。
  • 但是"王者荣耀"本身就是一个热词,比如还有 “老铁”,“一带一路” 等词语都是热词,但是IK词典里面都没有这些词,怎么办呢?好在IK分词器支持扩展,我们只需要经过简单的配置即可。

自定义中文词典步骤:

  1. 在/usr/local/elasticsearch-6.4.3/plugins/ik/config目录下
    vim custom/new_word.dic并添加需要的热词,例如下词语:
    老铁
    王者荣耀
    洪荒之力
    绝地求生
    一带一路

  2. 修改配置: vim IKAnalyzer.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <comment>IK Analyzer 扩展配置</comment>
    <!--用户可以在这里配置自己的扩展字典 -->
    <entry key="ext_dict">custom/new_word.dic</entry>
     <!--用户可以在这里配置自己的扩展停止词字典-->
    <entry key="ext_stopwords"></entry>
    <!--用户可以在这里配置远程扩展字典 -->
    <!-- <entry key="remote_ext_dict">words_location</entry> -->
    <!--用户可以在这里配置远程扩展停止词字典-->
    <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
  1. 重启Elasticsearch

测试使用自定义词典后:
在这里插入图片描述

7、Elasticsearch Mapping映射

文档映射

  1. 已经把ElasticSearch的核心概念和关系数据库做了一个对比,索引(index)相当于数据库,类型(type)相当于数据表,映射(Mapping)相当于数据表的表结构。
  2. ElasticSearch中的映射(Mapping)用来定义一个文档,可以定义所包含的字段以及字段的类型、分词器及属性等等。

文档映射就是给文档中的字段指定字段类型、分词器。

查看映射GET /myindex/user/_mapping

映射的分类

  1. 动态映射
    我们知道,在关系数据库中,需要事先创建数据库,然后在该数据库实例下创建数据表,然后才能在该数据表中插入数据。而ElasticSearch中不需要事先定义映射(Mapping),文档写入ElasticSearch时,会根据文档字段自动识别类型,这种机制称之为动态映射。

  2. 静态映射
    在ElasticSearch中也可以事先定义好映射,包含文档的各个字段及其类型等,这种方式称之为静态映射。

ES类型支持

  • 基本类型
  1. 字符串:string,string类型包含 text 和 keyword。
    text:该类型被用来索引长文本,在创建索引前会将这些文本进行分词,转化为词的组合,建立索引;允许es来检索这些词,text类型不能用来排序和聚合。
    keyword:该类型不需要进行分词,可以被用来检索过滤、排序和聚合,keyword类型自读那只能用本身来进行检索(不可用text分词后的模糊检索)。
    注意: keyword类型不能分词,Text类型可以分词查询
  2. 数值型:long、integer、short、byte、double、float
  3. 日期型:date
  4. 布尔型:boolean
  5. 二进制型:binary
  6. 数组类型(Array datatype)
  • 复杂类型
  1. 地理位置类型(Geo datatypes)
  2. 地理坐标类型(Geo-point datatype):geo_point 用于经纬度坐标
  3. 地理形状类型(Geo-Shape datatype):geo_shape 用于类似于多边形的复杂形状
  • 特定类型(Specialised datatypes)
  1. Pv4 类型(IPv4 datatype):ip 用于IPv4 地址
  2. Completion 类型(Completion datatype):completion 提供自动补全建议
  3. Token count 类型(Token count datatype):token_count 用于统计做子标记的字段的index数目,该值会一直增加,不会因为过滤条件而减少
  4. mapper-murmur3 类型:通过插件,可以通过_murmur3_来计算index的哈希值
  5. 附加类型(Attachment datatype):采用mapper-attachments插件,可支持_attachments_索引,例如 Microsoft office 格式,Open Documnet 格式, ePub,HTML等

在这里插入图片描述
Analyzer 索引分词器,索引创建的时候使用的分词器 比如ik_smart
Search_analyzer 搜索字段的值时,指定的分词器

创建文档类型并且指定类型

注:创建前确保index(数据库)为空,若不为空则删除索引 DELETE /myindex
然后再新建PUT /myindex

POST /myindex/_mapping/user
{
  "user":{
    "properties":{
       "age":{
         "type":"integer"
       },
        "sex":{
         "type":"integer"
       },
       "name":{
         "type":"text",
         "analyzer":"ik_smart",
         "search_analyzer":"ik_smart"
       },
       "car":{
         "type":"keyword",  # 数据类型为keyword,不支持分词
      	 "analyzer":"ik_smart", # 指定中文分词器 ik_smart
       }
    }
  }
  
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值