ElasticSearch 入门笔记 - 船新版本
来源 黑马讲义
目录
1. ElasticStack 简介
如果你没有听说过Elastic Stack,那你一定听说过ELK,实际上ELK是三款软件的简称,分别是Elasticsearch、
Logstash、Kibana组成,在发展的过程中,又有新成员Beats的加入,所以就形成了Elastic Stack。所以说,ELK
是旧的称呼,Elastic Stack是新的名字。
- ELK:ElaticSearch + Logstash + Kibana
全新的的ElasticStack包括
- ElasticSearch:ElasticSearch基于Java,是个开源分布式搜索引擎。他的特点有:分布式、零配置、自动发现、索引自动分片、索引副本机制、restful风格、多数据源、自动搜索负载等。
- Logstash:基于Java,是一个开源的用于收集,分析,和存储日志的工具。
- Kibana:基于nodejs,也是一个开源的免费的工具,Kibana可以为Logstash和ElasticSearch提供的日志分析友好的web界面,可以汇总,分析和搜索重要数据日志。
- Beats:是ElasticSearch公司开源的一款采集系统监控数据的代理agent,是在被监控服务器上以客户端形式运行的数据收集器的统称,可以直接把数据发送给ElasticSearch或者通过Logstash发送给ElasticSearch,然后进行后续的数据分析活动。
Beats组成
- Packetbeat:是一个网络数据包分析器,用于监控,收集网络流量信息。Packetbeat嗅探服务器之间的流量,解析应用层协议,并关联到消息的处理,其支持:ICMP(v4 and v6、DNS、HTTP、Mysql、PostgreSQL、Redis、MongoDB、Memcache等协议。
- Filebeat:用于监控、收集服务器日志文件。其已取代LogstashForwarder。
- Metricbeat:可定期获取外部系统的监控指标信息,其可监控,收集Apache、HAproxy、MongoDB、MySQL、Nginx、PostgreSQL、Redis、System、Zookeeper等服务
- Winlogbeat:用于监控、收集windwos系统的日志信息。
2. ElasticSearch简介
ElasticSearch是一个基于lucene的搜索服务器、他提供了一个分布式多用户能力的全文搜索引擎,基于RestFul Web接口。ElasticSearch是基于Java开发的,并作为Apache许可条款下的开放源代码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定、可靠、快速、安装使用方便。
官网:https://www.elastic.co/cn/products/elasticsearch
3. 安装
下载地址 https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-5-4
官网太慢了 使用百度网盘 如果下载还是慢 就充钱吧 没有什么是充钱解决不了的事 如果解决不了 那就多冲点
链接:https://pan.baidu.com/s/1uGajQ5n6zqFmix3xhIQSKQ
提取码:c2j3
3.1 window / linux 安装
3.1.1 编辑config / elasticsearch.yml

将network.host改为 127.0.0.1
注意看注释、看到下面就可以猜出来 http.port是指定es的http端口的
3.1.2 编辑 config / jvm.options

找到如上,改为上图中的值
3.1.3 启动
- Windows 执行 bin/elasticsearch.bat
- Linux 执行 bin/elasticsearch
3.1.4 测试
浏览器访问 127.0.0.1:9200 如图成功

3.2 Docker安装
#拉取镜像
docker pull elasticsearch:6.5.4
#创建容器
docker create --name elasticsearch --net host -e "discovery.type=single-node" -e
"network.host=172.16.55.185" elasticsearch:6.5.4
#启动
docker start elasticsearch
#查看日志
docker logs elasticsearch
自行测试
4. elasticsearch-head
官方没有提供es的图形化管理工具,elasticsearch-head是为es开发的一个页面客户端工具
官方地址 https://github.com/mobz/elasticsearch-head
windows安装 https://www.cnblogs.com/hts-technology/p/8477258.html
docker安装
#拉取镜像
docker pull mobz/elasticsearch-head:5
#创建容器
docker create --name elasticsearch-head -p 9100:9100 mobz/elasticsearch-head:5
#启动容器
docker start elasticsearch-head
5. 基本概念
索引
- 索引(index)是对逻辑数据的逻辑存储,所以他可以分为更小的部分
- 可以把索引看成关系型数据库的表,索引的结构是为快速有效的全文索引准备的,特别是他不存储原始值。
- 可以把索引看成MongoDB的一个集合
- es可以把索引存放在一台机器上或者分散在多台服务器上,每个索引有一个或多个分片(shard)。每个分片可以有多个副本(replica)
文档
- 存储在es中的主要实体叫文档(document)。用关系型数据库来类比的话,一个文档相当于数据库中的一行记录
- es和mongo中的文档类似,都可以有不同的结构。 但在es中,相同的字段必须有相同类型
- 文档由多个字段成,每个字段可能多次出现在一个文档中,这样的字段叫做多值字段(multivalued)
- 每个字段的类型。可以是文本,数值,日期等。字段类型有可以是复杂类型,一个字段包含其他子文档或者数组
映射
- 所有文档写进索引之前都会先进行分析,如何将输入的文本分割为词条,哪些词条又会被过滤,这种行为叫做映射(mapping)。
文档类型
- 在es中,一个索引对象可以存储很多不同用途的对象。例如,一个博客应用程序可以保存文章 评论。
- 每个文档都可以有不同的结构
- 不同的文档类型不能为相同的属性设置不同的类型。例如,在同一索引中的所有文档类型中,一个叫title 字段必须具同的相同的类型。
6. RESTful API
6.1 创建非结构化索引
6.1.1 创建空索引
PUT http://172.16.55.185:9200/haoke
{
"settings": {
"index": {
"number_of_shards": "2", #分片数
"number_of_replicas": "0" #副本数
}
}
}
#删除索引
DELETE http://172.16.55.185:9200/haoke
{
"acknowledged": true
}
6.1.2 插入数据
POST http://172.16.55.185:9200/{索引}/{类型}/{id}
POST http://172.16.55.185:9200/haoke/user/1001
#数据
{
"id":1001,
"name":"张三",
"age":20,
"sex":"男"
}
#响应
{
"_index": "haoke",
"_type": "user",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
6.1.3 更新数据
PUT http://172.16.55.185:9200/haoke/user/1001
{
"id":1001,
"name":"张三",
"age":21,
"sex":"女"
}
6.1.4 局部更新
#注意:这里多了_update标识
POST http://172.16.55.185:9200/haoke/user/1001/_update
{
"doc":{
"age":23
}
}
6.1.5 删除数据
DELETE http://172.16.55.185:9200/haoke/user/1001
6.2 搜索数据
6.2.1 根据id搜索数据
GET http://172.16.55.185:9200/haoke/user/BbPe_WcB9cFOnF3uebvr
6.2.2 搜索全部数据
GET http://172.16.55.185:9200/haoke/user/_search
6.2.3 关键字搜素数据
#查询年龄等于20的用户
GET http://172.16.55.185:9200/haoke/user/_search?q=age:20
6.3 DSL搜索
Elasticsearch提供丰富且灵活的查询语言叫做DSL查询(Query DSL),它允许你构建更加复杂、强大的查询。
DSL(Domain Specific Language特定领域语言)以JSON请求体的形式出现。
6.3.1 查询年龄大于30岁的男性用户
POST http://172.16.55.185:9200/haoke/user/_search
#请求数据
{
"query": {
"bool": {
"filter": {
"range": {
"age": {
"gt": 30
}
}
},
"must": {
"match": {
"sex": "男"
}
}
}
}
}
6.3.2 全文搜索
POST http://172.16.55.185:9200/haoke/user/_search
#请求数据
{
"query": {
"match": {
"name": "张三 李四"
}
}
}
6.4 高亮显示
POST http://172.16.55.185:9200/haoke/user/_search
{
"query": {
"match": {
"name": "张三 李四"
}
},
"highlight": {
"fields": {
"name": {}
}
}
}
6.5 聚合
POST http://172.16.55.185:9200/haoke/user/_search
{
"aggs": {
"all_interests": {
"terms": {
"field": "age"
}
}
}
}
7. 核心讲解
7.1 文档
在Elasticsearch中,文档以JSON格式进行存储,可以是复杂的结构,如:
{
"_index": "haoke",
"_type": "user",
"_id": "1005",
"_version": 1,
"_score": 1,
"_source": {
"id": 1005,
"name": "孙七",
"age": 37,
"sex": "女",
"card": {
"card_number": "123456789"
}
}
}
其中,card是一个复杂对象,嵌套的Card对象。
元数据(metadata)
- _index 文档存储的地方
- _type 文档代表的对象的类
- _id 文档的唯一标识
7.2 pretty
可以在查询url后面添加pretty参数,使得返回的json更易查看。

7.3 指定响应对象
在响应的数据中,如果我们不需要全部的字段,可以指定某些需要的字段进行返回。
GET http://172.16.55.185:9200/haoke/user/1005?_source=id,name
#响应
{
"_index": "haoke",
"_type": "user",
"_id": "1005",
"_version": 1,
"found": true,
"_source": {
"name": "孙七",
"id": 1005
}
}
如不需要返回元数据,仅仅返回原始数据,可以这样:
GET http://172.16.55.185:9200/haoke/user/1005/_source
还可以这样:
GET http://172.16.55.185:9200/haoke/user/1005/_source?_source=id,name
7.4 判断文档是否存在
如果我们只需要判断文档是否存在,而不是查询文档内容,那么可以这样:
HEAD http://172.16.55.185:9200/haoke/user/1005
7.5 批量操作
7.5.1 批量查询
POST http://172.16.55.185:9200/haoke/user/_mget
{
"ids" : [ "1001", "1003" ]
}
7.5.2 _bulk操作
在Elasticsearch中,支持批量的插入、修改、删除操作,都是通过_bulk的api完成的。
请求格式如下:(请求格式不同寻常)
{ action: { metadata }}\n
{ request body }\n
{ action: { metadata }}\n
{ request body }\n
批量插入数据:
{"create":{"_index":"haoke","_type":"user","_id":2001}}
{"id":2001,"name":"name1","age": 20,"sex": "男"}
{"create":{"_index":"haoke","_type":"user","_id":2002}}
{"id":2002,"name":"name2","age": 20,"sex": "男"}
{"create":{"_index":"haoke","_type":"user","_id":2003}}
{"id":2003,"name":"name3","age": 20,"sex": "男"}
注意最后一行的回车
批量删除:
{"delete":{"_index":"haoke","_type":"user","_id":2001}}
{"delete":{"_index":"haoke","_type":"user","_id":2002}}
{"delete":{"_index":"haoke","_type":"user","_id":2003}}
由于delete没有请求体,所以,action的下一行直接就是下一个action。
其他操作就类似了。
一次请求多少性能最高?
- 整个批量请求需要被加载到接受我们请求节点的内存里,所以请求越大,给其它请求可用的内存就越小。有一个最佳的bulk请求大小。超过这个大小,性能不再提升而且可能降低。
- 最佳大小,当然并不是一个固定的数字。它完全取决于你的硬件、你文档的大小和复杂度以及索引和搜索的负载。
- 幸运的是,这个最佳点(sweetspot)还是容易找到的:试着批量索引标准的文档,随着大小的增长,当性能开始降低,说明你每个批次的大小太大了。开始的数量可以在1000~5000个文档之间,如果你的文档非常大,可以使用较小的批次。
- 通常着眼于你请求批次的物理大小是非常有用的。一千个1kB的文档和一千个1MB的文档大不相同。一个好的批次最好保持在5-15MB大小间。
7.6 分页
如果你想每页显示5个结果,页码从1到3,那请求如下:
# size: 结果数,默认10
# from: 跳过开始的结果数,默认0
GET /_search?size=5
GET /_search?size=5&from=5
GET /_search?size=5&from=10
应该当心分页太深或者一次请求太多的结果。结果在返回前会被排序。但是记住一个搜索请求常常涉及多个
分片。每个分片生成自己排好序的结果,它们接着需要集中起来排序以确保整体排序正确。
在集群系统中深度分页
为了理解为什么深度分页是有问题的,让我们假设在一个有5个主分片的索引中搜索。当我们请求结果的第一
页(结果1到10)时,每个分片产生自己最顶端10个结果然后返回它们给请求节点(requesting node),它
再排序这所有的50个结果以选出顶端的10个结果。
现在假设我们请求第1000页——结果10001到10010。工作方式都相同,不同的是每个分片都必须产生顶端
的10010个结果。然后请求节点排序这50050个结果并丢弃50040个!你可以看到在分布式系统中,排序结果的花费随着分页的深入而成倍增长。这也是为什么网络搜索引擎中任
何语句不能返回多于1000个结果的原因。
7.7 映射
前面我们创建的索引以及插入数据,都是由Elasticsearch进行自动判断类型,有些时候我们是需要进行明确字段类
型的,否则,自动判断的类型和实际需求是不相符的。
自动判断的规则如下:

Elasticsearch中支持的类型如下:

- string类型在ElasticSearch 旧版本中使用较多,从ElasticSearch 5.x开始不再支持string,由text和keyword类型替代。
- text 类型,当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型。设置text类型以后,字段内容会被分析,在生成倒排索引以前,字符串会被分析器分成一个一个词项。text类型的字段不用于排序,很少用于聚合。
- keyword类型适用于索引结构化的字段,比如email地址、主机名、状态码和标签。如果字段需要进行过滤(比如查找已发布博客中status属性为published的文章)、排序、聚合。keyword类型的字段只能通过精确值搜索到。
创建明确类型的索引:
PUT http://172.16.55.185:9200/itcast
{
"settings": {
"index": {
"number_of_shards": "2",
"number_of_replicas": "0"
}
},
"mappings": {
"person": {
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "integer"
},
"mail": {
"type": "keyword"
},
"hobby": {
"type": "text"
}
}
}
}
}
查看映射:
GET http://172.16.55.185:9200/itcast/_mapping
http方式创建mapping
# 127.0.0.1:9200/purchaseinfo/purchaseinfo/_mapping?pretty
{
"purchaseinfo":{
"properties": {
"title": {
"type": "text"
},
"type": {
"type": "text"
},
"region": {
"type": "text"
},
"industry": {
"type": "text"
},
"detail": {
"type": "text"
},
"createDate": {
"type": "text"
}
}
}
}
7.8 结构化查询
7.8.1 term查询
term 主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed 的字符串(未经分析的文本数据类型):
POST http://172.16.55.185:9200/itcast/person/_search
{
"query" : {
"term" : {
"age" : 20
}
}
}
7.8.2 terms查询
terms 跟 term 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么文档需要一
起去做匹配:
POST http://172.16.55.185:9200/itcast/person/_search
{
"query" : {
"terms" : {
"age" : [20,21]
}
}
}
7.8.3 range查询
range 过滤允许我们按照指定范围查找一批数据
{
"range": {
"age": {
"gte": 20,
"lt": 30
}
}
}
- gt 大于
- gte 大于等于
- lt 小于
- lte 小于等于
POST http://172.16.55.185:9200/itcast/person/_search
{
"query": {
"range": {
"age": {
"gte": 20,
"lte": 22
}
}
}
}
7.8.4 exists 查询
exists 查询可以用于查找文档中是否包含指定字段或没有某个字段,类似于SQL语句中的 IS_NULL 条件
POST http://172.16.55.185:9200/haoke/user/_search
{
"query": {
"exists": { #必须包含
"field": "card"
}
}
}
7.8.5 match查询
match 查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到它
如果你使用 match 查询一个全文本字段,它会在真正查询之前用分析器先分析 match 一下查询字符
如果用 match 下指定了一个确切值,在遇到数字,日期,布尔值或者 not_analyzed 的字符串时,它将为你搜索
你给定的值
{ "match": { "age": 26 }}
{ "match": { "date": "2014-09-01" }}
{ "match": { "public": true }}
{ "match": { "tag": "full_text" }}
7.8.6 bool查询
bool 查询可以用来合并多个条件查询结果的布尔逻辑,它包含一下操作符
- must :: 多个查询条件的完全匹配,相当于 and 。
- must_not :: 多个查询条件的相反匹配,相当于 not 。
- should :: 至少有一个查询条件匹配, 相当于 or 。
这些参数可以分别继承一个查询条件或者一个查询条件的数组:
{
"bool": {
"must": { "term": { "folder": "inbox" }},
"must_not": { "term": { "tag": "spam" }},
"should": [
{ "term": { "starred": true }},
{ "term": { "unread": true }}
]
}
}
7.8.7 过滤查询
前面讲过结构化查询,Elasticsearch也支持过滤查询,如term、range、match等。
示例:查询年龄为20岁的用户。
POST http://172.16.55.185:9200/itcast/person/_search
{
"query": {
"bool": {
"filter": {
"term": {
"age": 20
}
}
}
}
}
查询和过滤的对比
- 一条过滤语句会询问每个字段值是否包含特定值
- 查询语句会询问每个文档的字段值与特定值的匹配度如何
- 一个简单的文档列表,快速匹配运算并存入内存是十分方便的,每个文档仅需要1个字节,这些缓存的过滤结果集与后续请求的结合使用是非常高效的
- 查询语句不仅要查询相匹配的文档,还需要计算每个文档的相关性,所以一般来说查询语句要比过滤语句更耗时,并且查询结果也不缓存。
建议:
做精确匹配时,最好用过滤语句,因为过滤语句可以缓存结果
8. 中文分词
8.1 什么是分词
词就是指将一个文本转化成一系列单词的过程,也叫文本分析,在Elasticsearch中称之为Analysis。
举例:我是中国人 --> 我/是/中国人
8.2 分词api
指定分词器进行分词
POST http://172.16.55.185:9200/_analyze
{
"analyzer":"standard",
"text":"hello world"
}
指定索引分词
POST http://172.16.55.185:9200/itcast/_analyze
{
"analyzer": "standard",
"field": "hobby",
"text": "听音乐"
}
8.3 内置分词
8.3.1 Standard
Standard 标准分词,按单词切分,并且会转化成小写
POST http://172.16.55.185:9200/_analyze
{
"analyzer": "standard",
"text": "A man becomes learned by asking questions."
}
8.3.2 Simple
Simple分词器,按照非单词切分,并且做小写处理
结果
{
"tokens": [
{
"token": "if",
"start_offset": 0,
"end_offset": 2,
"type": "word",
"position": 0
},
{
"token": "the",
"start_offset": 3,
"end_offset": 6,
"type": "word",
"position": 1
},
{
"token": "document",
"start_offset": 7,
"end_offset": 15,
"type": "word",
"position": 2
},
{
"token": "doesn",
"start_offset": 16,
"end_offset": 21,
"type": "word",
"position": 3
},
{
"token": "t",
"start_offset": 22,
"end_offset": 23,
"type": "word",
"position": 4
},
{
"token": "already",
"start_offset": 24,
"end_offset": 31,
"type": "word",
"position": 5
}
8.3.3 Whitespace
Whitespace是按照空格切分
POST http://172.16.55.185:9200/_analyze
{
"analyzer": "whitespace",
"text": "If the document doesn't already exist"
}
结果
{
"tokens": [
{
"token": "If",
"start_offset": 0,
"end_offset": 2,
"type": "word",
"position": 0
},
{
"token": "the",
"start_offset": 3,
"end_offset": 6,
"type": "word",
"position": 1
},
{
"token": "document",
"start_offset": 7,
"end_offset": 15,
"type": "word",
"position": 2
},
{
"token": "doesn't",
"start_offset": 16,
"end_offset": 23,
"type": "word",
8.3.3 Stop
Stop分词器,是去除Stop Word语气助词,如the、an等。
"analyzer": "stop"
结果
{
"tokens": [
{
"token": "document",
"start_offset": 7,
"end_offset": 15,
"type": "word",
"position": 2
},
{
"token": "doesn",
"start_offset": 16,
"end_offset": 21,
"type": "word",
"position": 3
},
{
"token": "t",
"start_offset": 22,
"end_offset": 23,
"type": "word",
"position": 4
},
{
"token": "already",
"start_offset": 24,
"end_offset": 31,
"type": "word",
"position": 5
},
{
"token": "exist",
"start_offset": 32,
"end_offset": 37,
"type": "word",
"position": 6
}
]
}
8.3.4 Keyword
Keyword分词器,意思是传入就是关键词,不做分词处理
"analyzer": "keyword"
结果
{
"tokens": [
{
"token": "If the document doesn't already exist",
"start_offset": 0,
"end_offset": 37,
"type": "word",
"position": 0
}
]
}
8.4 中文分词
中文分词的难点在于,在汉语中没有明显的词汇分界点,如在英语中,空格可以作为分隔符,如果分隔不正确就会
造成歧义。
常用中文分词器,IK、jieba、THULAC等,推荐使用IK分词器
IK Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始,
IKAnalyzer已经推出了3个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析
算法的中文分词组件。新版本的IK Analyzer 3.0则发展为面向Java的公用分词组件,独立于Lucene项目,同
时提供了对Lucene的默认优化实现。
采用了特有的“正向迭代最细粒度切分算法“,具有80万字/秒的高速处理能力 采用了多子处理器分析模式,支
持:英文字母(IP地址、Email、URL)、数字(日期,常用中文数量词,罗马数字,科学计数法),中文词
汇(姓名、地名处理)等分词处理。 优化的词典存储,更小的内存占用。
IK分词器 Elasticsearch插件地址:https://github.com/medcl/elasticsearch-analysis-ik
安装方法:将下载到的elasticsearch-analysis-ik-6.5.4.zip解压到/elasticsearch/plugins/ik 目录下即可
更多推荐



所有评论(0)