- 正向索引与倒排索引
- 正向索引
正排表是以文档的ID为关键字,表中记录文档中每个字的位置信息,查找时扫描表中每个文档中字的信息直到找出所有包含查询关键字的文档。
这种组织方法在建立索引的时候结构比较简单,建立比较方便且易于维护;因为索引是基于文档建立的,若是有新的文档加入,直接为该文档建立一个新的索引块,挂接在原来索引文件的后面。若是有文档删除,则直接找到该文档号文档对应的索引信息,将其直接删除。但是在查询的时候需对所有的文档进行扫描以确保没有遗漏,这样就使得检索时间大大延长,检索效率低下。
尽管正排表的工作原理非常的简单,但是由于其检索效率太低,除非在特定情况下,否则实用性价值不大。 - 倒排索引 (ElasticSearch使用倒排索引)
倒排表以字或词为关键字进行索引,表中关键字所对应的记录表项记录了出现这个字或词的所有文档,一个表项就是一个字表段,它记录该文档的ID和字符在该文档中出现的位置情况。
由于每个字或词对应的文档数量在动态变化,所以倒排表的建立和维护都较为复杂,但是在查询的时候由于可以一次得到查询关键字所对应的所有文档,所以效率高于正排表。在全文检索中,检索的快速响应是一个最为关键的性能,而索引建立由于在后台进行,尽管效率相对低一些,但不会影响整个搜索引擎的效率。
正排索引是从文档到关键字的映射(已知文档求关键字),倒排索引是从关键字到文档的映射(已知关键字求文档)
序号
文档内容
1
小俊是一家科技公司创始人,开的汽车是奥迪a8l,加速爽。
2
小薇是一家科技公司的前台,开的汽车是保时捷911
3
小红买了小薇的保时捷911,加速爽。
4
小明是一家科技公司开发主管,开的汽车是奥迪a6l,加速爽。
5
小军是一家科技公司开发,开的汽车是比亚迪速锐,加速有点慢
如图根据上面的文件记录,使用倒排索引会对以上文档内容进行关键词分词,可以使用关键次直接定位到文档内容。
单词ID
单词
倒排列表docId
1
小
1,2,3,4,5
2
一家
1,2,4,5
3
科技公司
1,2,4,5
4
开发
4,5
5
汽车
1,2,4,5
6
奥迪
1,4
7
加速爽
1,3,4
8
保时捷
2,3
9
保时捷911
2
10
比亚迪
5
- DSL语言查询与过滤
什么是DSL语言
es中的查询请求有两种方式,一种是简易版的查询,另外一种是使用JSON完整的请求体,叫做结构化查询(DSL)。
由于DSL查询更为直观也更为简易,所以大都使用这种方式。
DSL查询是POST过去一个json,由于post的请求是json格式的,所以存在很多灵活性,也有很多形式。
- 根据名称精确查询姓名 (英文)
##term是代表完全匹配,即不进行分词器分析,文档中必须包含整个搜索的词汇GET /basic/user/_search { "query": { "term": { "name": "liming" } } }
- 根据名称模糊查询
####match查询相当于模糊匹配,只包含其中一部分关键词就行GET /basic/user/_search { "from": 0, "size": 2, "query": { "match": { "name": "刘德" } } }
- Term与Match区别
Term查询不会对字段进行分词查询,会采用精确匹配。
Match会根据该字段的分词器,进行分词查询。
- 使用filter过滤年龄
GET /basic/user/_search { "query": { "bool": { "must": [{ "match_all": {} }], "filter": { "range": { "age": { "gt": 21, "lte": 51 } } } } }, "from": 0, "size": 10, "_source": ["name", "age"] }
- 中文分词器es-ik
如图: 如果我们对'奥迪a4l'进行分词查询的话,使用默认分词器,结果如下http://192.168.127.132:9200/_analyze { "analyzer": "standard", "text": "奥迪a4l" }
因为Elasticsearch中默认的标准分词器分词器对中文分词不是很友好,会将中文词语拆分成一个一个中文的汉子。因此引入中文分词器-es-ik插件。
安装步骤如下:
- 下载https://github.com/medcl/elasticsearch-analysis-ik/releases
注意: es-ik分词插件版本一定要和你的es安装的版本一样 - 解压
- 重命名为ik
- 上传
将重命名的ik文件上传到/usr/local/elasticsearch6.4/plugins - 重启elasticSearch
- 使用ik_smart分词器再次测试
http://192.168.127.132:9200/_analyze { "analyzer": "ik_smart", "text": "奥迪a4l" }
安装完成!!!
- 自定义扩展字典
- 创建自定义词典目录
cd /usr/local/elasticsearch6.4/plugins/ik/config mkdir my_test cd my_test
- 创建自定义词my_word.dic文件,文件内容如下
记住一定要先保存为UTF-8类型,否则上传后会乱码王者荣耀 地下城与勇士 QQ飞车
将文件上传到刚刚创建的my_test文件目录下
- 修改IKAnalyzer.cfg.xml 配置文件
//进入/usr/local/elasticsearch6.4/plugins/ik/config vi IKAnalyzer.cfg.xml // 配置my_test/my_word.dic词典文件 ######################################配置后的内容如下################################### <?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">my_test/my_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>
- 重启elasticSearch
- 使用Postman再次测试
POST: http://192.168.127.132:9200/_analyze // Body->raw { "analyzer": "ik_smart", "text": "王者荣耀" }
- 文档映射
把ElasticSearch的核心概念和关系数据库做对比,索引(index)相当于数据库,类型(type)相当于数据表,映射(Mapping)相当于数据表的表结构。ElasticSearch中的映射(Mapping)用来定义一个文档,可以定义所包含的字段以及字段的类型、分词器及属性等等。
文档映射就是给文档中的字段指定字段类型、分词器。
使用GET /mymayikt/user/_mapping - 映射的分类
- 动态映射
我们知道,在关系数据库中,需要事先创建数据库,然后在该数据库实例下创建数据表,然后才能在该数据表中插入数据。而ElasticSearch中不需要事先定义映射(Mapping),文档写入ElasticSearch时,会根据文档字段自动识别类型,这种机制称之为动态映射 - 静态映射
在ElasticSearch中也可以事先定义好映射,包含文档的各个字段及其类型等,这种方式称之为静态映射。
- ES类型支持
- 基本类型
字符串:string,string类型包含 text 和 keyword。
text:该类型被用来索引长文本,在创建索引前会将这些文本进行分词,转化为词的组合,建立索引;允许es来检索这些词,text类型不能用来排序和聚合。
keyword:该类型不需要进行分词,可以被用来检索过滤、排序和聚合,keyword类型自读那只能用本身来进行检索(不可用text分词后的模糊检索)。--应用场景少
注意: keyword类型不能分词,Text类型可以分词查询
数指型:long、integer、short、byte、double、float
日期型:date
布尔型:boolean
二进制型:binary
数组类型(Array datatype)
- 复杂类型
地理位置类型(Geo datatypes)
地理坐标类型(Geo-point datatype):geo_point 用于经纬度坐标
地理形状类型(Geo-Shape datatype):geo_shape 用于类似于多边形的复杂形状特定类型(Specialised datatypes)
Analyzer 索引分词器,索引创建的时候使用的分词器 比如ik_smart
Pv4 类型(IPv4 datatype):ip 用于IPv4 地址
Completion 类型(Completion datatype):completion 提供自动补全建议
Token count 类型(Token count datatype):token_count 用于统计做子标记的字段的index数目,该值会一直增加,不会因为过滤条件而减少
mapper-murmur3 类型:通过插件,可以通过_murmur3_来计算index的哈希值
附加类型(Attachment datatype):采用mapper-attachments插件,可支持_attachments_索引,例如 Microsoft office 格式,Open Documnet 格式, ePub,HTML等
Search_analyzer 搜索字段的值时,指定的分词器 - 创建文档并指定类型
####创建索引 PUT test ####创建文档并指定类型 analyzer:指定分词器 POST /test/_mapping/user { "user":{ "properties":{ "age":{ "type":"integer" }, "name":{ "type":"text", "analyzer":"ik_smart", "search_analyzer":"ik_smart" }, "address":{ "type":"keyword" } } } }
- 查看文档类型
###查看文档类型 GET /test/user/_mapping