ElasticSearch 入门笔记 - 船新版本

来源 黑马讲义

目录

1. ElasticStack 简介

2. ElasticSearch简介

3. 安装

        3.1 window / linux 安装

        3.2 Docker安装

4. elasticsearch-head

5. 基本概念

6. RESTful API

        6.1 创建非结构化索引

7. 核心讲解

        7.1 文档

        7.2 pretty

        7.3 指定响应对象

        7.4  判断文档是否存在

        7.5 批量操作

                7.5.1 批量查询

                7.5.2 _bulk操作

        7.6 分页

        7.7 映射

        7.8 结构化查询

                7.8.1 term查询

                7.8.2 terms查询

                7.8.3 range查询

                7.8.4 exists 查询

                7.8.5 match查询

                7.8.6 bool查询

                7.8.7 过滤查询

8. 中文分词

        8.1 什么是分词

        8.2 分词api

        8.3 内置分词

                8.3.1 Standard

                8.3.2 Simple

                8.3.3 Whitespace

                8.3.3 Stop

                8.3.4 Keyword

        8.4 中文分词


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可以为LogstashElasticSearch提供的日志分析友好的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

ElasticSearch 入门笔记 - 船新版本_第1张图片

将network.host改为 127.0.0.1 

注意看注释、看到下面就可以猜出来 http.port是指定es的http端口的

3.1.2 编辑 config / jvm.options

ElasticSearch 入门笔记 - 船新版本_第2张图片

找到如上,改为上图中的值

3.1.3 启动

  • Windows 执行 bin/elasticsearch.bat
  • Linux 执行 bin/elasticsearch

3.1.4 测试

浏览器访问 127.0.0.1:9200 如图成功

ElasticSearch 入门笔记 - 船新版本_第3张图片

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更易查看。

ElasticSearch 入门笔记 - 船新版本_第4张图片

 

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 入门笔记 - 船新版本_第5张图片

Elasticsearch中支持的类型如下:

ElasticSearch 入门笔记 - 船新版本_第6张图片

  • 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 目录下即可

 

你可能感兴趣的:(ElasticSearch 入门笔记 - 船新版本)