一、倒排索引
1、简介:倒排索引源于实际应用中需要根据属性的值来查找记录,这种索引表中的每一个项都包括一个属性值和具有该属性值的各记录的地址,由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而成为倒排索引,带有倒排索引的文件称之为倒排索引文件,简称倒排文件
2、示例
①例如有如下三个文件,A(文通过Python django搭建网站),B(通过Python scrapy爬取网站数据),C(scrapy-redis分布式爬虫)
②现在要查询,带有Python的文件,正常是对每个文件进行遍历,每个文件遍历一次,如果文件特别大,每个文件有一亿个字符,总共有一亿各文件,每个都要遍历,非常消耗资源
③存储文件之前,先对文件进行分析,将文件分词,对分词建立索引,例如下面
1 今天是星期天我们出去玩
2 明天是星期天,放假
3 今天天气很晴朗
4 xxx
5 他们出去玩了
| 关键词 |
文章 |
| 今天 |
文章1,文章3 |
| 星期天 |
文章2 |
| 出去玩 |
文章5,文章1 |
④es在做存储的时候,更详细,关键词出现在哪个文章,出现的位置和出现的次数都有记录
| 关键词 |
文章 |
| 今天 |
(文章1,<2,10>,2) (文章3,<8>,1) |
| 星期天 |
(文章2,<12,25,100>,3) |
| 出去玩 |
(文章5,<11,24,89>,3)(文章1,<8,19>,2) |
3、倒排索引待解决的问题
①大小写转换问题,如python和Python应该为同一个词
②词干抽取,looking和look应该处理为同一个词
③分词,如,屏蔽系统是屏蔽和系统两个词还是为屏蔽系统一个词
④倒排索引文件过大,需要压缩编码
二、索引操作
2、索引初始化
# 新建一个lqz2的索引,索引分片数量为5,索引副本数量为1
PUT lqz2
{
"settings": {
"index":{
"number_of_shards":5,
"number_of_replicas":1
}
}
}
# number_of_shards:每个索引的主分片数,默认值是 5 ,这个配置在索引创建后不能修改
# number_of_replicas:每个主分片的副本数,默认值是 1 ,对于活动的索引库,这个配置可以随时修改
3、查询索引配置
①获取lqz2索引的配置信息:GET lqz2/_settings
②获取所有索引的配置信息:GET _all/_settings 或者 GET _settings
③获取lqz和lqz2索引的配置信息:GET lqz,lqz2/_settings
4、更新索引
# 修改索引副本数量为2
PUT lqz/_settings
{
"number_of_replicas": 2
}
# 如遇到报错:cluster_block_exception
# 是由于ES新节点的数据目录data存储空间不足,导致从master主节点接收同步数据的时候失败,此时ES集群为了保护数据,会自动把索引分片index置为只读read-only
PUT _all/_settings
{
"index": {
"blocks": {
"read_only_allow_delete": false
}
}
}
5、删除索引:删除lqz索引 => DELETE lqz
三、映射操作
1、版本区别
①在Elasticsearch 6.0+中创建的索引只包含一个mapping type
②在5.0+中使用multiple mapping types创建的索引将继续像以前一样在Elasticsearch 6.0+中运行
③Mapping types在Elasticsearch 7.0+中完全删除
2、简介
①在创建索引的时候,可以预先定义字段的类型及相关属性
②如果输入了没有预先定义类型的字段,Es会根据Json数据源的基础类型,猜测映射的字段,将输入的数据转变成可以搜索的索引项
③Mapping是我们自己定义的字段数据类型,同时告诉es如何索引数据及是否可以被搜索
④Mapping会让索引建立的更加细致和完善
3、字段数据类型
①string类型:text,keyword
②数字类型:long,integer,short,byte,double,float
③日期类型:data
④布尔类型:boolean
⑤binary类型:binary
⑥复杂类型:object(实体,对象),nested(列表)
⑦geo类型:geo-point,geo-shape(地理位置)
⑧专业类型:ip,competion(搜索建议)
4、映射参数
| 属性 |
描述 |
适合类型 |
| store |
值为yes表示存储,no表示不存储,默认为no |
all |
| index |
yes表示分析,no表示不分析,默认为true |
text |
| null_value |
如果字段为空,可以设置一个默认值,比如"NA"(传过来为空,不能搜索,na可以搜索) |
all |
| analyzer |
可以设置索引和搜索时用的分析器,默认使用的是standard分析器,还可以使用whitespace,simple。都是英文分析器 |
all |
| include_in_all |
默认es为每个文档定义一个特殊域_all,它的作用是让每个字段都被搜索到,如果想让某个字段不被搜索到,可以设置为false |
all |
| format |
时间格式字符串模式 |
date |
5、创建索引
①text类型会取出词做倒排索引,keyword不会被分词,原样存储,原样匹配
②mapping类型一旦确定,以后就不能修改了
PUT books
{
"mappings": {
"properties":{
"title":{
"type":"text",
"analyzer": "ik_max_word"
},
"price":{
"type":"integer"
},
"addr":{
"type":"keyword"
},
"company":{
"properties":{
"name":{"type":"text"},
"company_addr":{"type":"text"},
"employee_count":{"type":"integer"}
}
},
"publish_date":{"type":"date","format":"yyy-MM-dd"}
}
}
}
③插入测试数据
# 测试数据1
PUT books/_doc/1
{
"title":"大头儿子小偷爸爸",
"price":100,
"addr":"北京天安门",
"company":{
"name":"我爱北京天安门",
"company_addr":"我的家在东北松花江傻姑娘",
"employee_count":10
},
"publish_date":"2019-08-19"
}
# 测试数据2
PUT books/_doc/2
{
"title":"白雪公主和十个小矮人",
"price":"99", # 写字符串会自动转换成数字
"addr":"黑暗森里",
"company":{
"name":"我的家乡在上海",
"company_addr":"朋友一生一起走",
"employee_count":10
},
"publish_date":"2018-05-19"
}
6、查看索引
①查看books索引的mapping:GET books/_mapping
②获取所有的mapping:GET _all/_mapping
四、文档操作
1、新增文档
#新增一个id为1的书籍(POST和PUT都可以)
POST lqz/_doc/1/_create
# POST lqz/_doc/1
# POST lqz/_doc 会自动创建id,必须用Post
{
"title":"红楼梦",
"price":12,
"publish_addr":{
"province":"黑龙江",
"city":"鹤岗"
},
"publish_date":"2013-11-11",
"read_num":199,
"tag":["古典","名著"]
}
2、查询文档
①查询lqz索引下id为7的文档:GET lqz/_doc/7
②查询lqz索引下id为7的文档,只要title字段:GET lqz/_doc/7?_source=title
③查询lqz索引下id为7的文档,只要title和price字段:GET lqz/_doc/7?_source=title,price
④查询lqz索引下id为7的文档,要全部字段:GET lqz/_doc/7?_source
3、修改文档
# 覆盖修改
PUT lqz/_doc/10
{
"title":"xxxx",
"price":333,
"publish_addr":{
"province":"黑龙江",
"city":"福州"
}
}
# 局部修改(注意是post)
POST lqz/_update/10
{
"doc":{
"title":"修改"
}
}
4、删除文档:删除文档id为10的 => DELETE lqz/_doc/10
5、批量操作之_mget
# 批量获取lqz索引_doc类型下id为2的数据和lqz2索引_doc类型下id为1的数据
GET _mget
{
"docs":[
{
"_index":"lqz",
"_type":"_doc",
"_id":2
},
{
"_index":"lqz2",
"_type":"_doc",
"_id":1
}
]
}
# 批量获取lqz索引下id为1和2的数据
GET lqz/_mget
{
"docs":[
{
"_id":2
},
{
"_id":1
}
]
}
# 同上
GET lqz/_mget
{
"ids":[1,2]
}
6、批量操作之 bulk
PUT test/_doc/2/_create
{
"field1" : "value22"
}
POST _bulk
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_id" : "2" } }
{ "create" : { "_index" : "test", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }