ElasticSearch基础
一、集群环境:
1)拷贝解压目录;
2)修改配置文件,内容如下;
#集群名称
cluster.name: xxsd-es
#节点名称,每个目录不一样
node.name: xxsd-node-232-1
#访问IP
network.host: 0.0.0.0
http.port: 19200
transport.tcp.port: 19300
#集群节点
discovery.zen.ping.unicast.hosts: ["127.0.0.1:19300","127.0.0.1:29300"]
#discovery.zen.minimum_master_nodes: 3
http.cors.enabled: true
http.cors.allow-origin: "*"
bootstrap.memory_lock: false
bootstrap.system_call_filter: false
##########################来源于网络##########################
cluster.name: wechat-es-cluster #集群的名字
node.name: es-node-1 #节点的名字 每个节点都不一样
node.master: true # 是否有资格成为主节点 我的机器是都可以成为主节点的
node.data: true # 是否可以成为数据节点 (主节点也可以成为数据节点)
path.data: /home/carsonlius/elasticsearch/data // 数据存储路径
path.logs: /home/carsonlius/elasticsearch/logs // 日志存储路径
network.host: 0.0.0.0 # 设置访问的地址和端口, 默认无法公开访问
http.port: 9200 # 设置访问的地址和端口
discovery.zen.ping.unicast.hosts: ["172.17.0.4", "172.17.0.2", "172.17.0.3", "172.17.0.5"] #集群的主机地址
discovery.zen.minimum_master_nodes: 3 # 防止脑裂 通常为 (可成为主节点的主机数目 / 2) + 1
gateway.recover_after_nodes: 3 # 最好3个节点 回应之后集群就可以继续工作
cluster.initial_master_nodes: ["es-node-4", "es-node-3", "es-node-2", "es-node-1"] #通过为 cluster.initial_master_nodes 参数设置一系列符合主节点条件的节点的主机名或 IP 地址来引导启动集群
查看集群信息:http://nexus.xianxianshidai.com:19200/_cluster/state?pretty
二、分布式索引:
2.1)number_of_shards
分片数量,类似数据的分表,一旦定义不可进行更改,会影响写操作;
8核16G:1个分片不要超过500G;
分布式索引一定要注意分片数量不能更改。所以在创建的时候一定要预先估算好数据的大小,一般在8核16G的机器上一个分片不要超过500G。索引会根据分片的配置来均匀的响应用户请求;
如果调整了分片,必须要进行重建索引;
假设前置条件:
目前有4条数据,ID分别为:1,2,3,4;
目前有2个分片,shards1、shards2;
在存储的时候会涉及算法:ID%分片个数;
根据算法得出如下结果:
数据1:1%2=1;
数据2:2%2=0;
数据3:3%2=2;
数据1:4%2=0;
最后数据存储就变成:数据1、3存在一个分片shards1,数据2、4存在一个分片shards2
如果这时修改了分片,那么之前的数据就不能获取到了,因此一旦发生了更改,就必须重建索引;
2.2)number_of_replicas
副本数,用于备份分片,与分片的数据保持一致,主要响应读操作,副本越多读取就越快;
三、读写
3.1)写数据
不管发到哪台机器都会转发到master机器,由他来确定当前这个文档(DOC)应该要存在哪个shards,用的Hash取模方式;
3.2)读数据
不一定会到master,因为每个Node里都存了节点信息;
四、ElasticSearch基础类型
|
名称 |
类型 |
说明 |
|
Text |
字符串类型 |
可以被拆词器处理 |
|
Keyword |
字符串类型 |
是对Text类型的补充,不会被拆词器处理,只能做精确匹配 |
|
Date |
日期类型 |
通常结合format使用; 例如:{"type":"date","format":"yyyy-MM-dd"} |
|
long、integer、short |
数字类型 |
|
|
boolean |
Boolean类型 |
取值范围:True或False |
|
Array |
数组类型 |
|
|
object |
对象类型 |
一般就是我们使用的Json数据对象 |
|
ip |
IP地址类型 |
|
|
geo_point |
地址位置类型 |
{“lat”:【维度】,"lon":【经度】} |
五、操作处理
所有的操作都是JSON格式的命令;
5.1)索引管理
5.1.1)创建命令:PUT
命令说明:
PUT /【索引名称】 { 【参数名称】:【值】 }
默认创建
PUT /test { }
默认情况下不带任何参数,会提示:“#! Deprecation: the default number of shards will change from [5] to [1] in 7.0.0; if you wish to continue using the default of [5] shards, you must manage this on the create index request or with an index template”表示系统会自动创建5个主分片,只建了1个副本;
指定分片
PUT /test { "settings": { "number_of_shards": 1, "number_of_replicas": 1 } }
调整配置
PUT /test/_settings { "number_of_replicas": 0 }
注意这里如果调整的是“number_of_shards”那么整个数据都要进行重建;
这里我们只调整“number_of_replicas”副本,副本数如果超过集群数量的情况,会出现不可用的情况;
5.1.3)结构化创建
是常规优化点,通过明确指定目标的定义,达到优化的目的;
顾名思义,在创建索引的时候就对数据有个预估及预判,根据数据内部的信息合理规划;
在查询过程中,尤其是分页查询,ES会到每个分片上去获取数据,然后再内存中进行处理,如果规划的分片过多会对内存的处理造成灾难性的影响;
PUT /test { "settings": { "number_of_shards": 【分配数量】, "number_of_replicas": 【副本数】 }, "mappings": { "_doc":{ "properties": { 【字段名称】:{"type": 【类型】} } } } }
5.1.4)删除命令:DELETE
命令说明
DELETE /【索引名称】
5.2)数据管理
5.2.1)创建数据
命令说明
PUT /【索引名称】/_doc/【ID】 { 【添加数据的名称】:【值】 }
默认创建
PUT /test/_doc/1 { "name":"xxsd", "age":30 }
这里注意一下默认创建,会自动赋予类型
{ "mapping": { "_doc": { "properties": { "age": { "type": "long" }, "name": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } } }
5.2.2)修改数据
命令说明
PUT /test/_doc/1 { "name":"xxsd1", "age":30 }
PUT是全量修改数据,没有提供的数据列会被删除;
POST /test/_doc/1/_update { "doc": { "name":"xxsd1" } }
POST是增量修改,不会修改其他的数据;此命令不但可以增量修改,也可以进行添加,添加方式如下;
POST /test/_doc/2/_create { "name":"xxsd", "age":30 }
5.2.3)删除数据
命令说明
DELETE /【索引名称】/_doc/【数据的ID】
5.2.4)读取数据
命令说明
#查询主键 GET /test/_doc/1 #查询所有 GET /test/_search { "query": { "match_all": {} } }
5.2.5)分页查询
ES分页数据有个致命的缺陷问题,不能查询太多的分页,以为ES在内存里进行分页处理的;一般来说数据分页不要超过10000;
命令说明
GET /test/_search { "query": { "match_all": {} }, "from": 0, "size": 2 }
5.2.6)根据条件查询
命令说明
GET /test/_search { "query": { "match": { 【条件列名】: 【条件值】 } } }
5.2.7)查询排序
命令说明
GET /test/_search { "query": { "match": { 【条件列名】: 【条件值】 } }, "sort": [ { 【排序字段】: { "order": 【排序类型:desc或asc】 } } ] }
5.2.8)聚合查询
命令说明
GET /test/_search { "query": { "match": { 【条件列名】: 【条件值】 } }, "sort": [ { 【排序字段】: { "order": 【排序类型:desc或asc】 } } ], "aggs": { 【自定义聚合名称】: { "terms": { "field": 【聚合字段名称】 } } } }
聚合类型很多,后面会有详细的API
六、分词器
6.1)stander
ElasticSearch默认分词器,把数据的每个字都分开;
“张三李四王五”会被分成:“张“,”三“,”李“,”四“,”王“,”五”;默认分词器会根据数据内容将数据的每个字都分开;
优点:足够细腻,只要满足一个都可以进行匹配;
缺点:消耗更多的性能,结果不够精确,不一定是我们需要的;
英文的处理:英文在处理分词的时候不仅仅进行分词,而会做标准化处理及停用词处理,例如:停用词被取缔、eating会变成eat,apples会变成appl;
命令说明
PUT /test { "settings": { "number_of_shards": 3, "number_of_replicas": 1 }, "mappings": { "_doc":{ "properties": { "name":{"type": "text", "analyzer": "standard【默认分词】"}, "enname":{"type": "text", "analyzer":"english【英文分词】"}, "age":{"type":"integer"} } } } } GET /test/_analyze { "field": 【字段名称】, "text": 【字段内容】 }
6.2)IK中文分词ElasticSearch插件
插件官方网址:https://github.com/medcl/elasticsearch-analysis-ik
安装命令:./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.6.0/elasticsearch-analysis-ik-6.6.0.zip
安装完毕后再plugins下会有一个analysis-ik的目录
安装时注意:
1)必须对应版本;
2)安装完毕后必须重启ElasticSearch;
3)修改或调整词库后必须重启ElasticSearch;
命令说明
PUT /test { "settings": { "number_of_shards": 3, "number_of_replicas": 1 }, "mappings": { "_doc":{ "properties": { "name":{"type": "text", "analyzer": "ik_max_word【IK分词】"}, "enname":{"type": "text", "analyzer":"english【英文分词】"}, "age":{"type":"integer"} } } } } GET /test/_analyze { "field": 【字段名称】, "text": 【字段内容】 }
示例说明
GET /test/_analyze { "field": "name", "text": "武汉市长江大桥" }
这是会发现“江大桥”没有被发现,检查步骤如下:
1)进入词库,进入目录/【ElasticSearch目录】/config/analysis-ik
2)查看词库,vim main.dic中有没有江大桥;
3)加入“江大桥”;
4)重启ElasticSearch;
5)再次运行,就发现可以被拆分成“江大桥”了;
IK分词器有2种模式:
1)ik_max_word:将能够拆分的词都拆分出来;
2)ik_smart:是使用的贪心算法,尽可能分配词长,以局部最优达到全局最优;
使用技巧:创建索引的时候使用ik_max_word,搜索的时候使用ik_smart,这样查询时仅查询少量的词就可以查询所有信息,优化了性能;
实例代码:
PUT /test { "settings": { "number_of_shards": 3, "number_of_replicas": 1 }, "mappings": { "_doc":{ "properties": { "name":{"type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart"}, "enname":{"type": "text", "analyzer":"english"}, "age":{"type":"integer"} } } } }
6.3)分词总结
既然使用了IK是不是stander就多余了呢?
IK依托词库,stander是内部默认,在实际使用过程中应该使用stander进行托底处理;可以建立了IK字段,再创建一个stander字段,如果IK找不到,再使用stander字段再检索一次,这样保证了最终的结果;
但是这种方式需要慎用,因为占用空间;
IK还可以进行砍词处理,砍词的谋略需要自己定义;
假设,我们系统里有“巴拉”这个品牌,输入的查找信息“欧巴拉”,那么我们检测到包含“巴拉”这个词,那么就把最后搜索的关键词中的“欧”去掉后再进行检索;
也有简单粗暴的方式:
从第一个词开始砍,一直砍到有为止;
从最后一个词开始砍,一直砍到有为止;
中文内容:选择IK;
英文内容:选择内置的分词器;
既有中文又有英文:选择IK;
NLP纠错处理????后面陆续补充;

浙公网安备 33010602011771号