Es 总结

原谅我不会排版,也懒得折腾。

在Nopad++里样式还不错

到这里就乱七八糟的。。

看不惯的 直接去下txt吧,样式会好一些。

地址:http://download.csdn.net/download/li_work/10018315


1.Es lucene Solr 基本概念 和区别


lucene,先进、功能强大的搜索库,直接基于lucene开发,非常复杂,api复杂(实现一些简单的功能,写大量的java代码),需要深入理解原理(各种索引结构)

Solr基于lucene实现了进一步的封装处理,更简单的开箱即用。


elasticsearch,基于lucene,隐藏复杂性,提供简单易用的restful api接口、java api接口(还有其他语言的api接口)
 1)分布式的文档存储引擎
 2)分布式的搜索引擎和分析引擎
 3)分布式,支持PB级数据

ES与solr的区别:
          1) Solr是提供类似webservice的接口。Es提供rest风格的接口。
          2) Solr 4.x以后支持分布式,而Es天生支持分布式,数据量越多ES搜索效率越高!
          3) Solr的数据格式是xml和json,Es是json
     4) Solr不支持实时数据搜索,而Es可以(从索引一个文档直到这个文档能够被搜索到有一个轻微的延迟(通常是1秒))

2.Es的特性以及应用场景
 1) 开源 
 2) 提供了JAVA API接口。 
 3) 提供了RESTful API接口
 4) REST请求和应答是典型的JSON格式
     5) 可以作为一个大型分布式集群(数百台服务器)技术,处理PB级数据,服务大公司;也可以运行在单机上,自定义主从备份,自主切换。
 6) 开箱即用,3分钟安装部署,非常小的耦合度。
 
Es的应用核心是大数据量下的数据搜索和数据分析。
搜索:聊天记录的关键字搜索
数据分析:APP用户日活量,搜索量最高的商品等等
业界内典型的使用场景:
  1) 百度百科,全文检索,高亮,搜索推荐
  2) 搜狐新闻,用户行为日志(点击,浏览,收藏,评论)
  3) 淘宝,搜索商品,(中文,拼音)
  
    3.Es的安装部署过程
Es最新版本为5.6.1 
历史版本为1.x 2.x 5.x,各版本安装部署差异较大。
        
这里主要讲基于Linux环境下的Es5.6.1版本安装。
环境要求:jdk1.8.0_81 及以上版本。我用的1.8.0_144,JDK安装自行百度。
cd /usr/local  (自定义的Es_Home)
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.6.1.tar.gz
tar -zxvfelasticsearch-5.6.1.tar.gz
安装完成 后台启动Es
bin/elasticsearch &  

部分报错问题:
Error:0x00007f2cae000000, 33554432, 0) failed; error='Cannot allocate memory' (errno=12)
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000085330000, 2060255232, 0) failed; error='Cannot allocate memory' (errno=12)
由于elasticsearch5.x默认分配jvm空间大小为2g,修改jvm空间分配,ES_HOME/config/jvm.options  -xms2g -xmx修改为 -xms512m -xmx512m
Error:can not run elasticsearch as root 
显然不能用root用户启动,新建用户并切换去启动。
Error:access denied
权限不够,用root赋予Es用户文件夹权限 chown esUser /usr/local -R
其余报错问题这里不占篇幅 参考 http://blog.csdn.net/li_work/article/details/78113614

启动成功,查看 ps -ef|grep elastic  

liunx运行: curl 127.0.0.1:9200 
返回当前IP下Es节点的状态信息:

{
 "name" : "Oj6ase4",
 "cluster_name" : "elasticsearch",
 "cluster_uuid" : "qbhH0ylgQp-PBARMkB_Peg",
 "version" : {
"number" : "5.6.1",
"build_hash" : "667b497",
"build_date" : "2017-09-14T19:22:05.189Z",
"build_snapshot" : false,
"lucene_version" : "6.6.1"
 },
 "tagline" : "You Know, for Search"
}

name:当前Es节点的实例名称。
cluster_name:当前Es节点的集群名称,若启动时不指定则默认为elasticsearch;
剩下就是Es版本的基本信息:版本号,构建时间,基于lucene的版本等。

注:外网或者局域网访问Es,需在Es_Home/config/elasticsearch.yml 中放开NetWork的注释,并将值从192.168.0.1修改为0.0.0.0 保存,重启Es生效。

4.Es的基本教程


集群:包含多个节点,每个节点属于哪个集群是通过一个配置(集群名称,默认是elasticsearch)来决定的
 节点只能通过指定某个集群的名字,来加入这个集群。
 
节点:名称(默认是随机分配的),节点名称很重要(在执行运维管理操作的时候),默认会去加入一个名称为“elasticsearch”的集群,
如果直接启动一堆节点,那么它们会自动组成一个elasticsearch集群,当然一个节点也可以组成一个elasticsearch集群

索引(index),类型(type) 和文档(document)
比较直观的说法是和典型的数据库进行对比:
Es            DB
index      database      每一个索引对应数据库里的一个库
type          table         每一个文档对应数据库里的一个表
document      record 每一个文档对应到表里的一条数据
区别在于在数据库表里存储某条数据时, 数据所包含的字段 必须等同于 表里所有的字段,多出字段会报错。
文档在插入type时可以多出来一些字段,多出的字段会在文档里自动添加映射。
举例:
DB: insert User(id,name) values(1,'zhangsan','男') 就会报错,因为user表里没有sex字段去存储 男。存储失败!
ES: 就会在索引的mapping里自动添加上一个field字段,并定义为String类型,并添加数据成功。  

document通常用JSON数据结构表示,
每个index下的type中,都可以去存储多个document。一个document里面有多个field,每个field就是一个数据字段

分片:当一个索引上存储上的数据超出了当前节点硬件存储的限制,Es允许索引上的数据进行化成多份,每份叫做一个分片,分片可以存储到当前集群上的
 其他节点上,通过分片可以水平分割/扩展你的内容容量,允许用户在分片之上进行分布式的、并行的操作,进而提高性能/吞吐量

复制:任何一个服务器随时可能故障或宕机,此时分片可能就会丢失,
 因此可以为每个分片创建多个复制的副本。副本可以在分片故障时提供备用服务,保证数据不丢失,
 多个副本还可以提升搜索操作的吞吐量和性能。
 分片(建立索引时一次设置,不能修改,默认5个),
 复制(随时修改数量,默认1个),默认每个索引10个shard,5个分片,5个备份副本,最小的高可用配置,是2台服务器

现在开始和es restful接口的一些基本通信:

/_cat Es提供的一些系统级的API查询restful 接口,返回均为json格式数据
curl 127.0.0.1:9200/_cat/health?v              检查集群的健康状态
curl 127.0.0.1:9200/_cat/nodes?v               获得节集群中的节点列表
curl 127.0.0.1:9200/_cat/indices?v             检查所有的索引信息
curl 127.0.0.1:9200/customer/_mapping?pretty   查看customer索引的当前mappping配置,返回当前索引Mapping,
      当新增的文档中存在mapping不存在的字段时,会自动根据字段类型映射到mapping中。

基本增删改查语句:
curl -XPUT 127.0.0.1:9200/customer?pretty      创建一个名字叫做customer的索引,参数pretty意思为返回的json格式化一下。
curl -XPUT 127.0.0.1:9200/customer/message/1?pretty -d '
{
 "name": "zhang san"
}'
给索引customer下类型为message中存入一条文档,文档字段名为name,值为 zhangsan,id指定为1,若不指定,则Es随机分配一个Id,并返回
curl 127.0.0.1:9200/customer/message/1?pretty   获取customer下message里id为1的文档信息。
curl 127.0.0.1:9200/customer/_search?pretty     获取customer索引下所有文档。
curl -XDELETE 127.0.0.1:9200/customer?pretty    删除customer索引
curl -XPOST 127.0.0.1:9200/customer/external/1/_update?pretty' -d '
{
 "doc": { "name": "Jane Doe" }
}'       修改语句

批处理语句 _bulk
curl -XPOST 127.0.0.1:9200/customer/external/_bulk?pretty -d '
{"update":{"_id":"1"}}
{"doc": { "name": "lisi" } }
{"delete":{"_id":"2"}}
首先更新了id为1的name字段,然后执行了删除id=2的文档。
bulk API按顺序执行这些动作。如果其中一个动作因为某些原因失败了,将会继续处理它后面的动作。
当bulk API返回时,它将提供每个动作的状态(按照同样的顺序),所以你能够看到某个动作成功与否。

进阶DSL(多条件搜索语句):
Elasticsearch提供一种JSON风格的特定领域语言,利用它你可以执行查询称为查询DSL。
具体方法参照SQL 基本就懂了。
curl -XPOST 127.0.01:9200/customer/_search?pretty -d '
{
 "query": { "match_all": {} }
}'
解析:select * from customer ;

curl -XPOST 127.0.01:9200/customer/_search?pretty -d '
{
 "query": { "match_all": {} },
 "size": 1
}'
解析:select * from customer limit 1; 注意,如果没有指定size的值,那么它默认就是10。

curl -XPOST 127.0.01:9200/customer/_search?pretty -d '
{
 "query": { "match_all": {} },
 "from": 10,
 "size": 10
}'
解析:select * from customer limit 10,10;

curl -XPOST 127.0.01:9200/customer/_search?pretty -d '
{
 "query": { "match_all": {} },
 "sort": { "balance": { "order": "desc" } }
}'
解析:select * from customer order by balance desc limit 0,10;

curl -XPOST 127.0.01:9200/customer/_search?pretty -d '
{
 "query": {
"bool": {
 "must": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
 ]
}
 }
}'
解析:select * from customer where address like "%mill%" and address like "%lane%";
{
  "query": {
    "match": {"name": "liu" }
  }, 
    "from":0,
    "size":10
}
curl -XPOST 127.0.01:9200/customer/_search?pretty -d '
{
 "query": {
"bool": {
 "must": [
{ "match": { "age": "40" } }
 ],
 "must_not": [
{ "match": { "state": "ID" } }
 ]
}
 }
}'
解析:select * from customer where age =40 and state not in ("ID");

curl -XPOST 127.0.01:9200/customer/_search?pretty -d '
{
 "size": 0,
 "aggs": {
"group_by_state": {
 "terms": {
"field": "state"
 }
}
 }
}'
解析:SELECT COUNT(*) from customer GROUP BY state ORDER BY COUNT(*) DESC

6.JAVA整合 Es API
Java结合Es有两种方式
一种是直接发送http请求Es暴露对外的restful接口,类似工具:url  httpClient等等 都可以实现。
   一种是用Es提供的Jar包进行调用实现。

这里主要讲一下JAVA整合 Es API
首先在项目中导入需要的maven依赖
<dependency>
              <groupId>org.elasticsearch</groupId>
              <artifactId>elasticsearch</artifactId>
              <version>5.3.1</version>
          </dependency>
<dependency>
 <groupId>org.elasticsearch.client</groupId>
 <artifactId>transport</artifactId>
 <version>5.3.1</version>
</dependency>

结合SpringCloud在项目的application.properties中定义好需要的配置变量,或者直接在config中统一配置管理
也可以在自己的代码中写死,测试练习用
es.cluster_name=elasticsearch
es.cluster_server_ip=47.93.6.131
es.index_name=customer
es.url=http://47.93.6.131:9200

Java Code:
@Value("${es.cluster_name}")
private String cluster_name;// 实例名称
@Value("${es.cluster_server_ip}")
private String cluster_serverip;// elasticSearch服务器ip
@Value("${es.index_name}")
private String indexname;// 索引名称



/**
* 返回一个到ElasticSearch的连接客户端

* @return
*/
private TransportClient getClient() {
Settings settings = Settings.builder().put("cluster.name", cluster_name).build();// 设置集群名称
TransportClient client = new PreBuiltTransportClient(settings);// 创建client
try {
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(cluster_serverip), 9300));// 增加地址和端口
} catch (UnknownHostException e) {
e.printStackTrace();
logger.error("ElasticSearch连接失败!");
}


return client;
}
这就创建了一个最基本的TransportClient,原理是利用IP地址和端口,集群名字,作为一个无存储的节点加入该集群,加入后就获取到了其他节点的信息
并通过指定的API进行通信!

参考了部分网上的资料,自己封装了一套API,
查询,搜索还是建议用url请求方式,快一些。
插入等操作用API好一些。


代码已上传 github 
地址:https://github.com/likaile/elasticSearcheDemo
欢迎加星

6.Es分词器
Es中,内置了很多分词器(analyzers),
standard (标准分词器) 默认分词器,最无脑的一个一个词(汉字)切分,所以适用范围广,但是精准度低
english  (英文分词)  对英文更加智能,可以识别单数负数,大小写,过滤stopwords
chinese  (中文分词)   Es提供给中文的一个分词器,但是效果很差。

所以我们要安装第三方的一个中文分词器,来达到我们想要的效果。
首先通过对比ik和chinese的分词效果来体现ik的好处。
chinese分词器
http://47.93.6.131:9200/index2/_analyze?analyzer=chinese&text=我爱你我的家&pretty 
   返回json:
{
"tokens": [
 {
"token": "我",
"start_offset": 0,
"end_offset": 1,
"type": "<IDEOGRAPHIC>",
"position": 0
},
 {
"token": "爱",
"start_offset": 1,
"end_offset": 2,
"type": "<IDEOGRAPHIC>",
"position": 1
},
 {
"token": "你",
"start_offset": 2,
"end_offset": 3,
"type": "<IDEOGRAPHIC>",
"position": 2
},
 {
"token": "我",
"start_offset": 3,
"end_offset": 4,
"type": "<IDEOGRAPHIC>",
"position": 3
},
 {
"token": "的",
"start_offset": 4,
"end_offset": 5,
"type": "<IDEOGRAPHIC>",
"position": 4
},
 {
"token": "家",
"start_offset": 5,
"end_offset": 6,
"type": "<IDEOGRAPHIC>",
"position": 5
}
],
}
可以看到和standard分词器一样很无脑的分成了一个一个的单个索引,

对比ik
http://47.93.6.131:9200/index2/_analyze?analyzer=ik_max_word&text=我爱你我的家&pretty 
返回json:
{
"tokens": [
 {
"token": "我爱你",
"start_offset": 0,
"end_offset": 3,
"type": "CN_WORD",
"position": 0
},
 {
"token": "爱你",
"start_offset": 1,
"end_offset": 3,
"type": "CN_WORD",
"position": 1
},
 {
"token": "你我",
"start_offset": 2,
"end_offset": 4,
"type": "CN_WORD",
"position": 2
},
 {
"token": "的",
"start_offset": 4,
"end_offset": 5,
"type": "CN_CHAR",
"position": 3
},
 {
"token": "家",
"start_offset": 5,
"end_offset": 6,
"type": "CN_CHAR",
"position": 4
}
],
}
很明显 IK分词 就友好了很多。
ik 带有两个分词器 ,这里用的是ik_max_word
ik_max_word :会将文本做最细粒度的拆分;尽可能多的拆分出词语 
ik_smart:会做最粗粒度的拆分;已被分出的词语将不会再次被其它词语占有 

ik的安装和使用过程。
参考 github原文  https://github.com/medcl/elasticsearch-analysis-ik
1.download or compile   


optional 1 - download pre-build package from here: https://github.com/medcl/elasticsearch-analysis-ik/releases


unzip plugin to folder your-es-root/plugins/


optional 2 - use elasticsearch-plugin to install ( version > v5.5.1 ):


./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v5.6.1/elasticsearch-analysis-ik-5.6.1.zip


2.restart elasticsearch


方法1:下载zip包,解压到 your-es-home/plugs/ik 下 
方法2 使用es插件下载 版本要大于5.5.1  
最后一步,重启ES
很简单,
因为索引的Mapping不可以删除,所以我们新建一个索引,并配置mapping进行测试。


curl -XPUT http://localhost:9200/index1

curl -XPOST http://localhost:9200/index1/message/_mapping -d'  
{  
"properties": {  
"content": {  
"type": "text",  
"analyzer": "ik_max_word",  
"search_analyzer": "ik_max_word"  
}  
}  
 
}'
新建索引index1,类型message,设置字段content, 设置搜索分词器为ik。

搜索关键字content 我爱你   返回 我爱你我的家 成功。

pinyin分词器
参考原文 https://github.com/medcl/elasticsearch-analysis-pinyin
首先来看下pinyin分词器 对于我爱你我的家的分词效果
{  
 "tokens" : [  
{  
 "token" : "wo",  
 "start_offset" : 0,  
 "end_offset" : 1,  
 "type" : "word",  
 "position" : 0  
},  
{  
 "token" : "ai",  
 "start_offset" : 1,  
 "end_offset" : 2,  
 "type" : "word",  
 "position" : 1  
},  
{  
 "token" : "ni",  
 "start_offset" : 2,  
 "end_offset" : 3,  
 "type" : "word",  
 "position" : 2  
},  
{  
 "token" : "wo",  
 "start_offset" : 3,  
 "end_offset" : 4,  
 "type" : "word",  
 "position" : 3  
},  
{  
 "token" : "de",  
 "start_offset" : 4,  
 "end_offset" : 5,  
 "type" : "word",  
 "position" : 4  
},  
{  
 "token" : "jia",  
 "start_offset" : 5,  
 "end_offset" : 6,  
 "type" : "word",  
 "position" : 5  
},  
{  
 "token" : "wanwdj",  
 "start_offset" : 0,  
 "end_offset" : 6,  
 "type" : "word",  
 "position" : 5  
}  
 ]  
}
pinyin的分词器和IK一样 下载ZIP,解压到plugs 下 pinyin文件夹  重启。


根据官方git地址 测试案例 整合一个索引进行 数据的拼音搜索   测试成功。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值