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

分片数量,类似数据的分表,一旦定义不可进行更改,会影响写操作;

816G1个分片不要超过500G

分布式索引一定要注意分片数量不能更改。所以在创建的时候一定要预先估算好数据的大小,一般在816G的机器上一个分片不要超过500G。索引会根据分片的配置来均匀的响应用户请求;

如果调整了分片,必须要进行重建索引;

 

假设前置条件:

目前有4条数据,ID分别为:1,2,3,4

目前有2个分片,shards1shards2

在存储的时候会涉及算法:ID%分片个数;

根据算法得出如下结果:

数据11%2=1;

数据22%2=0;

数据33%2=2;

数据14%2=0;

最后数据存储就变成:数据13存在一个分片shards1,数据24存在一个分片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"}

longintegershort

数字类型

 

boolean

Boolean类型

取值范围:TrueFalse

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": 【排序类型:descasc      }    }  ] }

 

5.2.8)聚合查询

命令说明

GET /test/_search {  "query": {    "match": {      【条件列名】: 【条件值】    }  },  "sort": [    {      【排序字段】: {        "order": 【排序类型:descasc      }    }  ],  "aggs": {    【自定义聚合名称】: {      "terms": {        "field": 【聚合字段名称】      }    }  } }

聚合类型很多,后面会有详细的API

 

六、分词器

6.1)stander

ElasticSearch默认分词器,把数据的每个字都分开;

张三李四王五会被分成:;默认分词器会根据数据内容将数据的每个字都分开;

优点:足够细腻,只要满足一个都可以进行匹配;

缺点:消耗更多的性能,结果不够精确,不一定是我们需要的;

英文的处理:英文在处理分词的时候不仅仅进行分词,而会做标准化处理及停用词处理,例如:停用词被取缔、eating会变成eatapples会变成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_wordIK分词】"},        "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种模式:

1ik_max_word:将能够拆分的词都拆分出来;

2ik_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纠错处理????后面陆续补充;

posted @ 2020-01-04 20:35  xxsd  阅读(288)  评论(0)    收藏  举报