一、概述

1、简介

ElasticSearch是一个基于Lucene实现的开源、分布式、Restful的全文本搜索引擎;此外,它还是一个分布式实时文档存储,其中每个文档的每个field均是被索引的数据,且可被搜索;也是一个带实时分析功能的分布式搜索引擎,能够扩展至数以百计的节点实时处理PB级的数据。

应用场景:当我们建立一个网站或应用程序,并要添加搜索功能,但是想要完成搜索工作的创建是非常困难的。我们希望搜索解决方案要运行速度快、能有一个零配置和一个完全免费的搜索模式、能够简单地使用JSON通过HTTP来索引数据、搜索服务器始终可用、一台开始并扩展到数百台,并且实时搜索,我们要简单的多租户,我们希望建立一个云的解决方案。因此我们利用Elasticsearch来解决所有这些问题以及可能出现的更多其它问题。

设计用途:用于分布式全文检索 

技术支持:通过HTTP使用JSON进行数据索引

主要目的:解决对于搜索的众多需求

2、基本组件

索引(index):文档容器,换句话说,索引是具有类似属性的文档的集合。类似于表。索引名必须使用小写字母;

类型(type):类型是索引内部的逻辑分区,其意义完全取决于用户需求。一个索引内部可定义一个或多个类型。一般来说,类型就是拥有相同的域的文档的预定义。

文档(document):文档是Lucene索引和搜索的原子单位,它包含了一个或多个域。是域的容器;基于JSON格式表示。每个域的组成部分:一个名字,一个或多个值;拥有多个值的域,通常称为多值域;

映射(mapping):原始内容存储为文档之前需要事先进行分析,例如切词、过滤掉某些词等;映射用于定义此分析机制该如何实现;除此之外,ES还为映射提供了诸如将域中的内容排序等功能。

4、ES的集群组件

Cluster:ES的集群标识为集群名称;默认为"elasticsearch"。节点就是靠此名字来决定加入到哪个集群中。一个节点只能属性于一个集群。

Node:运行了单个ES实例的主机即为节点。用于存储数据、参与集群索引及搜索操作。节点的标识靠节点名。

Shard:将索引切割成为的物理存储组件;但每一个shard都是一个独立且完整的索引;创建索引时,ES默认将其分割为5个shard,用户也可以按需自定义,创建完成之后不可修改。

shard有两种类型:primary shard和replica。Replica用于数据冗余及查询时的负载均衡。每个主shard的副本数量可自定义,且可动态修改。

5、ES Cluster工作过程

启动时,通过多播(默认)或单播方式在9300/tcp查找同一集群中的其它节点,并与之建立通信。

集群中的所有节点会选举出一个主节点负责管理整个集群状态,以及在集群范围内决定各shards的分布方式。站在用户角度而言,每个均可接收并响应用户的各类请求。

集群有状态:green, red, yellow

6、其他

ES的默认端口:

参与集群的事务:9300/tcp

transport.tcp.port

接收请求:9200/tcp

http.port

二、安装配置ElasticSearch

1、系统环境

操作系统:一台CentOS release 6.9(主节点),两台CentOS release 6.7(其他节点) 

ElasticSearch版本:elasticsearch-5.5.2.rpm 

JDK版本:java-1.8.0-openjdk 

注:由于ElasticSearch依赖Java环境,所以必须安装JDK。而且JDK版本必须在1.7以上。

2、安装并配置java环境

yum install  java-1.8.0-openjdk-1.8.0.102-4.b14.el7.x86_64.rpm
vim /etc/profile.d/java.sh

添加:

export JAVA_HOME=/usr/bin/java

注:我的java在/usr/bin下,可以通过which命令查找下确切位置。

3、安装ElasticSearch

yum install elasticsearch-5.5.2.rpm

注:安装完成后有以下提示信息

ELK 之 ElasticSearch

简单编辑配置elasticsearch文件:

vim /etc/elasticsearch/elasticsearch.ym

主节点添加cluster以及node名称:

ELK 之 ElasticSearch

其他节点添加cluster以及node名称(cluster命名一样,node分别命名):

ELK 之 ElasticSearch

另一台:

ELK 之 ElasticSearch

启动elasticsearch服务:

service elasticsearch start

ELK 之 ElasticSearch

查看监听端口:

ELK 之 ElasticSearch

通过CURL访问Elasticsearch进行检测是否正常:

curl -X GET 'http://127.0.0.1:9200/?pretty'

ELK 之 ElasticSearch

Curl访问Elasticsearch格式:

curl -X<VERB> '<PROTOCOL>://HOST:PORT/<PATH>?<QUERY_STRING>' -d '<BODY>'
VERB: GET, PUT, DELETE等;
PROTOCOL: http, https
QUERY_STRING:查询参数,例如?pretty表示用易读的JSON格式输出;
BODY: 请求的主体;

例:
curl -X GET‘http://127.0.0.1:9200/?help’通过“?help”获取帮助 
[[email protected] ~]# curl -X GET http://127.0.0.1:9200/_cat/nodes?h=name,ip,port,uptime,heap,current
Centos 127.0.0.1 9300 33.6m

查看集群监控状况(health):
curl -XGET 'http://127.0.0.1:9200/_cluster/health?pretty' 

查看集群状态(state):
curl -XGET 'http://127.0.0.1:9200/_cluster/state/?pretty' 

查看集群节点状态(stats):
curl -XGET 'http://127.0.0.1:9200/_nodes/stats?pretty'

问题:

1.在启动elasticsearch的时候,内存占用过大:

由于安装的elasticsearch为5.5版本,此版本默认heap设置为2G.

可以编辑jvm.options配置文件进行设置。

ELK 之 ElasticSearch

2.不能访问elasticsearch9200端口:

可以修改elasticsearch.yml配置文件,

network.host: 192.168.137.100
http.port: 9200

4、Elasticsearch的插件(Plugins)

Elasticsearch扩展性很强,可以通过安装插件实现功能的扩展。通过插件扩展ES功能如添加自定义的映射类型、自定义分析器、本地脚本、自定义发现方式。

Plugins的安装:

安装方式有两种:

1)直接将插件放置于/usr/share/elasticsearch/plugins目录中;

2)使用/usr/share/elasticsearch/bin/elasticsearch-plugins脚本进行安装(可以通过加参数"-h"获取帮助信息);

例:安装x-pack

/usr/share/elasticsearch/bin/elasticsearch-plugin install x-pack

X-Pack是一个Elastic Stack的扩展,将安全,警报,监视,报告和图形功能包含在一个易于安装的软件包中。 

在Elasticsearch 5.0.0之前,您必须安装单独的Shield,Watcher和Marvel插件才能获得在X-Pack中所有的功能。 

站点插件访问格式:

http://HOST:9200/_plugin/{plugin_name}

三、ElasticSearch的使用

1、Elasticsearch CRUD操作相关的API

1)创建文档:

curl -XPUT 'localhost:9200/students/class1/1?pretty' -d '
>{
>   "first_name": "fan",
>   "gender": "male",
>   "age": 23,
>   "courses": "it"
>}'

curl -XPUT 'localhost:9200/students/class1/1' -d '{ "first_name": "fan","age": 25,"sex":"male"}'

2)获取文档:

curl -XGET 'localhost:9200/students/class1/1?pretty'
{
  "_index" : "students",
  "_type" : "class1",
  "_id" : "1", #插入时指定的id=1,xxx/class1/1(id)?pretty
  "_version" : 1,
  "found" : true,
  "_source" : {
    "first_name" : "fan",
    "age" : 25,
    "sex" : "male"
  }
}

3)更新文档(两种方法)

1.PUT方法(会覆盖原有文档)

2.如果只更新部分内容,可以使用_update API

curl -XPOST 'localhost:9200/students/class1/1/_update?pretty' -d '
> {
>  "doc": {"age": 23}
> }'
{
  "_index" : "students",
  "_type" : "class1",
  "_id" : "1", 
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  }
}

4)删除文档

删除文档指定id就可以。(删除id为3的内容)

curl -XDELETE 'localhost:9200/students/class1/3?pretty'
{
  "found" : true,
  "_index" : "students",
  "_type" : "class1",
  "_id" : "3",
  "_version" : 4,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  }
}

在重新查找id为3的文档,结果已经删除。

ELK 之 ElasticSearch

5)删除索引

查看索引:(使用_cat API)

curl -XGET 'localhost:9200/_cat/indices?v'

ELK 之 ElasticSearch

删除索引:(指定索引节点即可)

curl -XDELETE 'localhost:9200/students'
{"acknowledged":true}

再次查看索引:(已经删除)

ELK 之 ElasticSearch


2、查询数据

查询数据我们需要使用elasticsearch的"Query" API,“Query”API是elasticsearch最重要的一部分。主要用于实现搜索功能。

"Query"API通过Query DSL(JSON based language for building complex queries)来实现,Query DSL可以实现

诸多类型的查询操作,如simple term query,phrase,range boolean,fuzzy等。

ES的查询操作执行分为两个阶段:1)分散阶段 2)合并阶段:

查询方式:

向ES发起查询请求的方式有两种:

1、通过Restful request API查询,也称为query string;

2、通过发送REST request body进行;(可以查询更为复杂的查询)

例方法一查询:查询student索引下所有文档(查询较小数据文档)

[[email protected] ~]# curl -XGET 'localhost:9200/students/_search?pretty'
{
  "took" : 1063,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "students",
        "_type" : "class1",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "third_name" : "jing",
          "age" : 25,
          "sex" : "female"
        }
      },
      {
        "_index" : "students",
        "_type" : "class1",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "third_name" : "fan",
          "age" : 23,
          "sex" : "male"
        }
      }
    ]
  }
}

例方法二查询:

[[email protected] ~]# curl -XGET 'localhost:9200/students/_search?pretty' -d '
> {
>  "query": {"match_all": {}}
> }'
{
  "took" : 11,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "students",
        "_type" : "class1",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "third_name" : "jing",
          "age" : 25,
          "sex" : "female"
        }
      },
      {
        "_index" : "students",
        "_type" : "class1",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "third_name" : "fan",
          "age" : 23,
          "sex" : "male"
        }
      }
    ]
  }
}

多索引、多类型查询:

    /_search:所有索引;

    /INDEX_NAME/_search:单索引;

    /INDEX1,INDEX2/_search:多索引;

    /s*,t*/_search:

    /students/class1/_search:单类型搜索

    /students/class1,class2/_search:多类型搜索

Mapping和Analysis:

什么是Mapping?

映射

为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成全文本(Full-text

)或精确的字符串值,Elasticsearch需要知道每个字段里面都包含了什么类型。这些类型和字段的

信息存储(包含)在映射(mapping)中。

正如《数据吞吐》一节所说,索引中每个文档都有一个类型(type)。 每个类型拥有自己的映射

(mapping)或者模式定义(schema definition)。一个映射定义了字段类型,每个字段的数据类型,以

及字段被Elasticsearch处理的方式。映射还用于设置关联到类型上的元数据。

这里只是入门。

例如,可以使用映射来定义:

字符串字段是否作为全文本搜索字段

哪些字段包含数字,日期或地理信息

文档中所有字段的值是否应该被索引到_all字段

日期值的格式

自定义规则来控制动态添加的字段的映射

映射类型与type:即一个索引中有多个type,从逻辑上对文档进行划分、每个索引有一个或多个映射

类型,类型是对Document划分的逻辑组,索引中每个文档都有一个类型(type),每个类型拥有自己的

映射或者模式定义(schema definition) 。每个映射类型包括:

1.关联到类型上的元数据,比如:_index, _type, _id, and _source

2.字段或属性的定义,比如:字段类型,每个字段的数据类型,以及字段被ES处理的方式。

数据类型大致分类:

简单类型,比如:string, date, long, double, boolean 或 ip等

嵌套对象

特殊类型,比如:geo_point, geo_shape, 或completion等

简单来讲mapping在Elasticsearch中的作用就是约束。


Elasticsearch对每一个文档,会取得其所有域的所有值,生成一个名为“_all”的域;执行查询时,如果在query_string未指定查询的域,则在_all域上执行查询操作;

GET .../_search?q='Xianglong'
GET .../_search?q='Xianglong%20Shiba%20Zhang'
GET .../_search?q=courses:'Xianglong%20Shiba%20Zhang'
GET .../_search?q=courses:'Xianglong'

前两个:表示在_all域搜索;

后两个:在指定的域上搜索;

例子:

ELK 之 ElasticSearch
ELK 之 ElasticSearch

查看指定类型的mapping示例:

curl 'localhost:9200/students/_mapping/class1?pretty'

ELK 之 ElasticSearch


什么是Analysis?

分析和分析器

分析(analysis)是这样一个过程:

首先,标记化一个文本块为适用于倒排索引单独的词(term)

然后标准化这些词为标准形式,提高它们的“可搜索性”或“查全率”

这个工作是分析器(analyzer)完成的。一个分析器(analyzer)只是一个包装用于将三个功能放到一个

包里:

功能1:字符过滤器

首先字符串经过字符过滤器(character filter),它们的工作是在标记化前处理字符串。字符过滤器

能够去除HTML标记,或者转换"&"为"and"。

功能2:分词器

下一步,分词器(tokenizer)被标记化成独立的词。一个简单的分词器(tokenizer)可以根据空格或逗

号将单词分开(译者注:这个在中文中不适用)。

功能3:标记过滤

最后,每个词都通过所有标记过滤(token filters),它可以修改词(例如将"Quick"转为小写),去

掉词(例如停用词像"a"、"and"、"the"等等),或者增加词(例如同义词像"jump"和"leap")

Elasticsearch提供很多开箱即用的字符过滤器,分词器和标记过滤器。这些可以组合来创建自定义

的分析器以应对不同的需求。

内建的分析器

不过,Elasticsearch还附带了一些预装的分析器,你可以直接使用它们。下面我们列出了最重要的

几个分析器,来演示这个字符串分词后的表现差异:

"Set the shape to semi-transparent by calling set_trans(5)"

Elasticsearch内置的分析器:Standard analyzer;Simple analyzer;Whitespace analyzer;Language analyzer

标准分析器(Standard analyzer)

标准分析器是Elasticsearch默认使用的分析器。对于文本分析,它对于任何语言都是最佳选择(译

者注:就是没啥特殊需求,对于任何一个国家的语言,这个分析器就够用了)。它根据Unicode 

Consortium的定义的单词边界(word boundaries)来切分文本,然后去掉大部分标点符号。最后,把

所有词转为小写。产生的结果为:

set, the, shape, to, semi, transparent, by, calling, set_trans, 5

简单分析器(Simple analyzer)

简单分析器将非单个字母的文本切分,然后把每个词转为小写。产生的结果为:

set, the, shape, to, semi, transparent, by, calling, set, trans

空格分析器(Whitespace analyze)

空格分析器依据空格切分文本。它不转换小写。产生结果为:

Set, the, shape, to, semi-transparent, by, calling, set_trans(5)

语言分析器(Language analyzer)

特定语言分析器适用于很多语言。它们能够考虑到特定语言的特性。例如,english分析器自带一套

英语停用词库——像and或the这些与语义无关的通用词。这些词被移除后,因为语法规则的存在,英

语单词的主体含义依旧能被理解(译者注:stem English words这句不知道该如何翻译,查了字典,

我理解的大概意思应该是将英语语句比作一株植物,去掉无用的枝叶,主干依旧存在,停用词好比枝

叶,存在与否并不影响对这句话的理解。)。

english分析器将会产生以下结果:

set, shape, semi, transpar, call, set_tran, 5

注意"transparent"、"calling"和"set_trans"是如何转为词干的。

分析器不仅在创建索引时用到;在构建查询时也会用到.


ElasticSearch查询语法(Query DSL)

Elasticsearch查询分为两类:

query 查询:执行full-text查询时,基于相关度来评判其匹配结果;查询执行过程复杂,且不会被缓存;

filter 查询(过滤查询):执行exact查询时,基于其结果为“yes”或“no”进行评判;速度快,且结果缓存;

查询语句的结构:

全文查询:

{
    QUERY_NAME: {
        AGGUMENT: VALUE,
        ARGUMENT: VALUE,...
    }
}

某个字段上查询:

{
    QUERY_NAME: {
        FIELD_NAME: {
            ARGUMENT: VALUE,...
        }
    }
}

filter 查询:

term filter:精确匹配包含指定term的文档;{ "term": {"name": "Guo"} }

[[email protected] ~]#curl -X GET 'localhost:9200/students/_search?pretty' -d '
> {
>   "query":{
>      "term": {
>          "name":"fan"
> }
> }
> }'

结果:

ELK 之 ElasticSearch


terms filter:用于多值精确匹配;{ "terms": { "name": ["Guo", "Rong"] }}

[[email protected] ~]# curl -X GET 'localhost:9200/students/_search?pretty' -d '
{
  "query":{
     "terms": {
         "name":["fan","jing"]
}
}
}'

结果:

ELK 之 ElasticSearch

range filters:用于在指定的范围内查找数值或时间;

{ "range": 
"age": {
"gte": 15,
"lte": 25
}
}

范围比较字符:gt(大于), lt(小于), gte(大于等于), lte(小于等于)


exists and missing filters:存在或者不存在;

{ 
"exists": {
"age": 25
}
}

boolean filter:

基于boolean的逻辑来合并多个filter子句;

must:其内部所有的子句条件必须同时匹配,即and;

must: {
"term": { "age": 25 }
"term": { "gender": "Female" }
}

must_not:其所有子句必须不匹配,即not

must_not: {
    "term": { "age": 25 }
}

should:至少有一个子句匹配,即or

should: {
"term": { "age": 25 }
"term": { "gender": "Female" }
}

QUERY 查询:

match_all Query:用于匹配所有文档,没有指定任何query,默认即为match_all query.

{ "match_all": {} }

match Query:在几乎任何域上执行full-text或exact-value查询;

如果执行full-text查询:首先对查询时的语句做分析;

{ "match": {"students": "Guo" }}

如果执行exact-value查询:搜索精确值;此时,建议使用过滤,而非查询;

{ "match": {"name": "Guo"} }

multi_match Query:用于在多个域上执行相同的查询;

{
"multi_match":
"query": full-text search
"field": {'field1', 'field2'}
}
{
"multi_match":
"query": {
"students": "Guo"
}
"field":
{
"name",
"description"
}
}

bool query:

基于boolean逻辑合并多个查询语句;与bool filter不同的是,查询子句不是返回"yes"或"no",而是其计算出的匹配度分值。因此,boolean Query会为各子句合并其score;

关键词:must: must_not: should:


合并filter和query查询语句(组合查询):

一般来讲可以filter语句嵌套到query语句用来过滤,但很少把query语句嵌套到filter语句上。

{
"filterd": {
query: { "match": {"gender": "Female"} }
filter: { "term": {"age": 25}}
}
}

查询语句语法检查:

GET /INDEX/_validate/query?pretty
{
    #查询语句
}

例子:

curl -XGET 'localhost:9200/students/_validate/query?pretty' -d '{"query": {"term": {"name": "fan"}}}'

ELK 之 ElasticSearch

如果想获取详细信息,可以使用以下格式:

GET /INDEX/_validate/query?explain&pretty
{
    #查询语句
}

例子:

curl -XGET 'localhost:9200/students/_validate/query?explain&pretty' -d '{"query": {"term": {"name": "fan"}}}'

ELK 之 ElasticSearch



官方站点:https://www.elastic.co/

转载于:https://blog.51cto.com/bovin/1963980

分类:

技术点:

相关文章: