ElasticSearch安装与基础使用入门

ElasticSearch安装与基础使用入门

关于ElasticSearch是什么,可以参考ES的官方文档中的介绍:Elasticsearch Introduction,中文版请见:ElasticSearch功能简介和系统介绍。本文针对了解ES可以做什么之后,来介绍如何安装ES以及使用ES进行一些基本操作(使用REST APIs进行数据存储、搜索和分析),作为ES的入门内容。

本文的内容主要包括如下步骤:

  1. 搭建ElasticSearch本地集群环境并运行ES
  2. ES中导入示例数据(单个文件/批量导入)
  3. 使用ElasticSearch Query Language搜索数据
  4. 使用Bucket和Metrics Aggregations(聚合)进行结果分析

本文内容参考自ElasticSearch官方文档:Getting started with Elasticsearch

ElasticSearch环境搭建并运行

使用Elastic Cloud运行ES

可以使用Elastic Cloud来构建ES的运行环境,在Elasticsearch Service上创建部署时,该服务与Kibana和APM一起预配一个三节点Elasticsearch集群。但目前阿里云,AWS和腾讯云提供的ES服务均为收费版本,因此这里不采用这种ES环境构建方式。如果需要使用Elastis Cloud,创建的方式具体见:Run Elasticsearch on Elastic Cloud

使用这种方式创建ES运行环境后,就无需进行下面的本地环境搭建过程,直接可以进行数据的导入和开发过程。

Elasticsearch本地运行环境构建

在Elasticsearch Service上创建部署时,将自动设置一个主节点和两个数据节点。 通过下面tar或zip安装,则可以在本地启动Elasticsearch的多个实例,以构建多节点集群的环境。下面进行本地三个节点ES运行环境的安装过程。

构建本地运行环境过程

1. 根据自己的OS环境下载对应的安装文件:

Linux: elasticsearch-7.6.2-linux-x86_64.tar.gz

curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.6.2-linux-x86_64.tar.gz

macOS: elasticsearch-7.6.2-darwin-x86_64.tar.gz

curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.6.2-darwin-x86_64.tar.gz

Windows: elasticsearch-7.6.2-windows-x86_64.zip

2. 解压安装文件:

Linux:

tar -xvf elasticsearch-7.6.2-linux-x86_64.tar.gz

macOS:

tar -xvf elasticsearch-7.6.2-darwin-x86_64.tar.gz

Windows PowerShell:

Expand-Archive elasticsearch-7.6.2-windows-x86_64.zip

3. 从解压目录bin中启动Elasticsearch:

Linux and macOS:

cd elasticsearch-7.6.2/bin
./elasticsearch

Windows:

cd elasticsearch-7.6.2\bin
.\elasticsearch.bat

启动完成后,现在就有一个ES的单实例成功运行了。

4. 下面启动另外两个Elasticsearch实例,来构建典型的多节点集群环境,此时在启动多个ES实例时,需要为每个节点指定唯一的数据和日志路径。

Linux and macOS:

./elasticsearch -Epath.data=data2 -Epath.logs=log2
./elasticsearch -Epath.data=data3 -Epath.logs=log3

Windows:

.\elasticsearch.bat -E path.data=data2 -E path.logs=log2
.\elasticsearch.bat -E path.data=data3 -E path.logs=log3

上面为新增的其他节点分配了唯一的ID,此时由于所有三个节点均为本地一个主机中运行,因此它们会自动与第一个节点一起加入到集群中。

使用Cat Health API验证集群运行状态

完成上述的安装和运行过程后,可以使用ElasticSearch提供的cat health API验证三节点集群是否正在运行。 cat API以比原始JSON更易于阅读的格式返回有关集群和索引的信息。可以通过向Elasticsearch REST API提交HTTP请求来直接与集群交互。 如果已安装并正在运行Kibana,则也可以打开Kibana并通过开发控制台提交请求。

运行下面的命令来启动Cat Health API:

curl -X GET "localhost:9200/_cat/health?v&pretty"

返回的响应信息如下,其中elasticsearch green表明了Elasticsearch集群的状态为绿色,并且具有三个节点:

epoch      timestamp cluster       status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1565052807 00:53:27  elasticsearch green           3         3      6   3    0    0        0             0                  -                100.0%

说明:如果仅运行单个Elasticsearch实例,则集群状态为黄色。 单节点群集虽然具有完整的功能,但是无法将数据复制到另一个节点以提供弹性。 副本分片在集群环境中可用,此时ES状态为绿色。 如果集群状态为红色,则表明某些数据不可用。

使用cURL向ElasticSearch提交请求

下面使用cURL命令,向本地ElasticSearch实例发送请求,进行相关的操作。Elasticsearch的请求与HTTP请求结构类似,包含如下组成部分:

curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'

其中具有的可用变量如下:

<VERB>
    The appropriate HTTP method or verb. For example, GET, POST, PUT, HEAD, or DELETE.
<PROTOCOL>
    Either http or https. Use the latter if you have an HTTPS proxy in front of Elasticsearch or you use Elasticsearch security features to encrypt HTTP communications.
<HOST>
    The hostname of any node in your Elasticsearch cluster. Alternatively, use localhost for a node on your local machine.
<PORT>
    The port running the Elasticsearch HTTP service, which defaults to 9200.
<PATH>
    The API endpoint, which can contain multiple components, such as _cluster/stats or _nodes/stats/jvm.
<QUERY_STRING>
    Any optional query-string parameters. For example, ?pretty will pretty-print the JSON response to make it easier to read.
<BODY>
    A JSON-encoded request body (if necessary).

如果启用了Elasticsearch安全功能,则还必须提供有权运行API的有效用户名(和密码)。 例如,使用-u或--u cURL命令参数。 有关运行每个API所需的安全特权的详细信息,请参阅REST APIs

Elasticsearch使用HTTP状态代码(例如200 OK)响应每个API请求。 除了HEAD请求之外,它还返回一个JSON编码的响应主体。

其他ES安装选项

其他具体的ElasticSearch安装选项和配置见:Installing Elasticsearch

ES中导入示例数据

完成上述的集群安装和启动后,就可以向ES导入一些数据并建立索引(index)了。 Elasticsearch有多种数据导入选项,但最终都是使用相同的方式:使用JSON将数据导入Elasticsearch索引中

单个索引文件提交

可以使用简单的PUT请求直接执行数据导入操作,该请求指定要添加文档的索引、唯一的文档ID、以及请求body中的一个或多个“filed”:“value” 对:

PUT /customer/_doc/1
{
  "name": "John Doe"
}
  • customer为ES的index
  • _doc为索引的类型:文档类型
  • 1:为该索引创建文档的ID 

 以上写法是ElasticSearch提供的cURl简写表达方式,没有加上完整的curl命令格式,完整的命令如下:

curl -X PUT "localhost:9200/customer/_doc/1?pretty" -H 'Content-Type: application/json' -d
'
{
  "name": "John Doe"
}
'

说明:下面的命令主要使用简写的命令方式,完整的命令可以根据该示例进行拼接使用。 

如果该索引尚不存在,此请求将自动创建该索引,添加ID为1的新文档,并存储name字段并为其建立索引。由于这是一个新文档,因此该请求的响应结果显示该操作创建了该文档的版本1:

{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 26,
  "_primary_term" : 4
}

创建完成后,可以从集群中的任何节点使用新文档,使用文档ID的GET请求检索该数据:

GET /customer/_doc/1

-- curl
curl -X GET "localhost:9200/customer/_doc/1?pretty"

 得到的响应如下,表明找到了具有指定ID的文档,并显示了已索引的源字段:

{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 26,
  "_primary_term" : 4,
  "found" : true,
  "_source" : {
    "name": "John Doe"
  }
}

使用Bulk批量提交索引文件

如果有很多要索引的文档,则可以使用bulk API批量提交数据到ES。 使用批量处理文档操作比单独提交请求要快得多,因为它可以最大程度地减少网络往返次数。

最佳批处理大小取决于许多因素:文档大小和复杂性,索引的建立和搜索负载以及集群的可用资源情况。 一般的建议是一次批处理1,000至5,000个文档,总的有效文件大小在5MB至15MB之间。

要将多个数据批量导入Elasticsearch,可以进行如下过程:

1. 下载 accounts.json 示例数据集。 此随机生成的数据集中的文档代表具有以下信息的用户帐户:

{
    "account_number": 0,
    "balance": 16623,
    "firstname": "Bradshaw",
    "lastname": "Mckenzie",
    "age": 29,
    "gender": "F",
    "address": "244 Columbus Place",
    "employer": "Euron",
    "email": "bradshawmckenzie@euron.com",
    "city": "Hobucken",
    "state": "CO"
}

2. 然后通过以下_bulk请求将帐户数据索引到bank索引中:

curl -H "Content-Type: application/json" -XPOST "localhost:9200/bank/_bulk?pretty&refresh" --data-binary "@accounts.json"
curl "localhost:9200/_cat/indices?v"

4. 如下的返回信息表示响应表明1,000个文档被成功索引:

health status index uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   bank  l7sSYV2cQXmu6_4rJWVIww   5   1       1000            0    128.6kb        128.6kb

使用ElasticSearch Query Language搜索数据

将一些数据导入到Elasticsearch索引后,就可以通过将请求发送到_search端点来进行搜索。 如果需要使用全面的搜索功能,可以使用Elasticsearch Query DSL在请求body中指定搜索条件。 并可以在请求URI中指定要搜索的索引名称。

例如,以下请求将检索bank索引中的所有文档并按帐号排序:

GET /bank/_search
{
  "query": { "match_all": {} },
  "sort": [
    { "account_number": "asc" }
  ]
}

-- curl
curl -X GET "localhost:9200/bank/_search?pretty" -H 'Content-Type: application/json' -d '
{
  "query": { "match_all": {} },
  "sort": [
    { "account_number": "asc" }
  ]
}
'

默认情况下,返回的响应内容中,``hits''部分包括符合搜索条件的前10个文档:
 

{
  "took" : 63,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
        "value": 1000,
        "relation": "eq"
    },
    "max_score" : null,
    "hits" : [ {
      "_index" : "bank",
      "_type" : "_doc",
      "_id" : "0",
      "sort": [0],
      "_score" : null,
      "_source" : {"account_number":0,"balance":16623,"firstname":"Bradshaw","lastname":"Mckenzie","age":29,"gender":"F","address":"244 Columbus Place","employer":"Euron","email":"bradshawmckenzie@euron.com","city":"Hobucken","state":"CO"}
    }, {
      "_index" : "bank",
      "_type" : "_doc",
      "_id" : "1",
      "sort": [1],
      "_score" : null,
      "_source" : {"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
    }, ...
    ]
  }
}

该响应内容中还提供有关搜索请求的以下信息:

  • took – how long it took Elasticsearch to run the query, in milliseconds
  • timed_out – whether or not the search request timed out
  • _shards – how many shards were searched and a breakdown of how many shards succeeded, failed, or were skipped.
  • max_score – the score of the most relevant document found
  • hits.total.value - how many matching documents were found
  • hits.sort - the document’s sort position (when not sorting by relevance score)
  • hits._score - the document’s relevance score (not applicable when using match_all)

每个搜索请求都是独立的:Elasticsearch在请求中不维护任何状态信息。 如果要浏览搜索结果,则需要在请求中指定from和size参数。例如,以下命令获取返回数据的第10个数据开始,到19个数据(包含的size为10):

GET /bank/_search
{
  "query": { "match_all": {} },
  "sort": [
    { "account_number": "asc" }
  ],
  "from": 10,
  "size": 10
}

-- curl
curl -X GET "localhost:9200/bank/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": { "match_all": {} },
  "sort": [
    { "account_number": "asc" }
  ],
  "from": 10,
  "size": 10
}
'

现在,上面已经了解了如何提交基本的搜索请求,下面开始构建比match_all更有趣的查询。要在字段中搜索特定术语,可以使用匹配(match)查询。 例如,以下请求在``地址''字段中搜索以查找其地址包含``mill''或``lane''的客户:

GET /bank/_search
{
  "query": { "match": { "address": "mill lane" } }
}

-- curl
curl -X GET "localhost:9200/bank/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": { "match": { "address": "mill lane" } }
}
'

如果要执行短语搜索而不是匹配单个术语,请使用match_phrase而不是match。 例如,以下请求仅匹配包含短语“ mill lane”的地址:

GET /bank/_search
{
  "query": { "match_phrase": { "address": "mill lane" } }
}

-- curl
curl -X GET "localhost:9200/bank/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": { "match_phrase": { "address": "mill lane" } }
}
'

要构造更复杂的查询,可以使用布尔查询来组合多个查询条件,根据需要(must match),期望(should match)或不期望(must not match)指定条件。例如,以下请求在bank索引中搜索属于40岁客户的账户,但不包括居住在爱达荷州(ID)的任何人:

GET /bank/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "age": "40" } }
      ],
      "must_not": [
        { "match": { "state": "ID" } }
      ]
    }
  }
}

-- curl
curl -X GET "localhost:9200/bank/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "bool": {
      "must": [
        { "match": { "age": "40" } }
      ],
      "must_not": [
        { "match": { "state": "ID" } }
      ]
    }
  }
}
'

Boolean查询中的每个must,should和must_not元素被称为查询子句。 文档满足每个must和should子句条件的程度决定了每个文档的相关性评分(relevance score)。 分数越高,文档就越符合期望的搜索条件。 默认情况下,Elasticsearch返回按这些相关性分数排名的文档。

“must_not”子句中的条件被视为过滤器。 它会影响文档是否包含在结果中,但不会影响文档的评分方式。 也可以显式的指定任意过滤器,以根据结构化的数据包括或排除文档。

例如,以下请求使用范围过滤器将结果限制为余额在20,000美元到30,000美元(含)之间的帐户。

GET /bank/_search
{
  "query": {
    "bool": {
      "must": { "match_all": {} },
      "filter": {
        "range": {
          "balance": {
            "gte": 20000,
            "lte": 30000
          }
        }
      }
    }
  }
}

-- curl
curl -X GET "localhost:9200/bank/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "bool": {
      "must": { "match_all": {} },
      "filter": {
        "range": {
          "balance": {
            "gte": 20000,
            "lte": 30000
          }
        }
      }
    }
  }
}
'

使用Bucket和Metrics Aggregations(聚合)进行结果分析

Elasticsearch的聚合功能能够获取有关搜索结果的元信息,并回答诸如“德克萨斯州有多少个帐户持有人”之类的问题,或“田纳西州的平均帐户余额是多少?” 使用aggregation功能可以在一个请求中搜索文档,过滤命中并使用汇总分析结果。

例如,以下请求按state使用terms对bank索引的所有账户进行分组,并按降序返回帐户数量最多的十个州:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      }
    }
  }
}

-- curl
curl -X GET "localhost:9200/bank/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      }
    }
  }
}
'

得到的请求响应如下,响应中的buckts是state字段的值,doc_count显示每个state下的帐户数。 例如,可以看到ID(Idaho)中有27个帐户。 由于请求的size= 0,因此返回的结果仅包含聚合的结果。

{
  "took": 29,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped" : 0,
    "failed": 0
  },
  "hits" : {
     "total" : {
        "value": 1000,
        "relation": "eq"
     },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "group_by_state" : {
      "doc_count_error_upper_bound": 20,
      "sum_other_doc_count": 770,
      "buckets" : [ {
        "key" : "ID",
        "doc_count" : 27
      }, {
        "key" : "TX",
        "doc_count" : 27
      }, {
        "key" : "AL",
        "doc_count" : 25
      }, {
        "key" : "MD",
        "doc_count" : 25
      }, {
        "key" : "TN",
        "doc_count" : 23
      }, {
        "key" : "MA",
        "doc_count" : 21
      }, {
        "key" : "NC",
        "doc_count" : 21
      }, {
        "key" : "ND",
        "doc_count" : 21
      }, {
        "key" : "ME",
        "doc_count" : 20
      }, {
        "key" : "MO",
        "doc_count" : 20
      } ]
    }
  }
}

也可以组合聚合以构建更复杂的数据汇总。 例如,以下请求在上一个group_by_state聚合中嵌套一个平均(avg)聚合,以计算每个州的平均账户余额。

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}
-- curl
curl -X GET "localhost:9200/bank/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}
'

可以通过在terms聚合内指定顺序来使用嵌套聚合的结果进行排序,而不是按计数(count值)对结果进行排序:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword",
        "order": {
          "average_balance": "desc"
        }
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

-- curl
curl -X GET "localhost:9200/bank/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword",
        "order": {
          "average_balance": "desc"
        }
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}
'

除了以上基本的bucket和metrics聚合外,Elasticsearch还提供了专门的聚合,用于在多个字段上操作并分析特定类型的数据,例如日期,IP地址和地理数据。 还可以将单个聚合的结果发送到pipeline aggregations中,以进行进一步分析。

此外,聚合提供的核心分析功能中具有其他高级功能,例如使用机器学习来检测异常等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值