elasticsearch 是什么?
Elasticsearch是一个高度可扩展的开源全文搜索和分析引擎。它允许你快速、近实时地存储、搜索和分析大量数据。它通常被用作底层引擎/技术,为具有复杂搜索功能和要求的应用提供动力
应用场景
案例1 你运行一个在线的网络商店,让你的客户搜索你销售的产品。在这种情况下,你可以使用Elasticsearch来存储您的整个产品目录和库存和为他们提供搜索和自动完成的建议
案例2 你想收集日志和交易数据,要分析和挖掘这些数据,寻找趋势,统计,总结,或异常。在这种情况下,你可以使用LogStash(的Elasticsearch / LogStash / Kibana堆栈的一部分)的收集、汇总,并分析你的数据,然后这些数据到Elasticsearch Logstash饲料。一旦数据在Elasticsearch,你可以搜索和聚合的矿山,你感兴趣的任何信息
案例3 您运行价格提醒平台,可以让价格精明的客户指定一个规则,如“我有兴趣购买一个特定价格的电子小工具,如果小工具的在下个月的价格低于X美元时,信息通知我”。在这种情况下,你可以把供应商的价格,把他们推到Elasticsearch和使用反向搜索(过滤器)的能力来匹配客户查询价格走势,一旦发现价格符合客户需求,最终将警报发送到客户。
案例4 你有分析/商业智能的需求,并希望迅速调查,分析,可视化,并要求特设的问题,在大量的数据(认为数以百万计或数十亿的记录)。在这种情况下,你可以使用Elasticsearch来存储你的数据,然后用Kibana(的Elasticsearch / LogStash / Kibana堆栈的一部分)建立自定义的仪表板,可以想象,重要的是你的数据方面。此外,您可以使用Elasticsearch的聚合功能来执行复杂的商业智能与数据查询
elasticsearch 的核心概念
1 准实时性 Elasticsearch是近实时搜索平台
2 集群 群集是一个或多个节点(服务器)的集合,它们一起保存整个数据,并在所有节点上提供联合索引和搜索功能。一个集群由一个唯一的名称默认为“Elasticsearch”。
3 节点 节点是单个服务器,它是群集的一部分,存储数据,并参与群集的索引和搜索功能。就像一个集群,一个节点是由一个名称,默认情况下是一个随机惊叹字符名称被分配到节点在启动。如果不希望默认,可以定义任何节点名。这个名字很重要,管理的目的,你要确定你的网络服务器对应于你的Elasticsearch群集节点。可以通过群集名称配置节点以连接特定的群集。
4 索引 索引是具有相似特性的文档集合。索引由名称(必须全部为小写)标识,该名称用于在对其中的文档执行索引、搜索、更新和删除操作时引用索引
5 类型 在索引中,可以定义一个或多个类型。类型是索引的逻辑类别/分区,其语义完全取决于您。一般来说,类型定义为具有公共字段集的文档。例如,假设你运行一个博客平台,并将所有数据存储在一个索引中。在这个索引中,您可以定义用户数据的类型,博客数据的另一种类型,以及注释数据的另一类型。
6 文档 文档是可以被索引的信息的基本单位。例如,您可以为单个客户提供文档,单个产品的另一个文档,以及单个订单的另一个文档。本文件是表示在JSON格式。在索引/类型中,您可以存储尽可能多的文档。请注意,尽管文档物理驻留在索引中,文档实际上必须索引或分配到索引中的类型
7 分片和复制
分片主要有两个原因是很重要的:
它允许您水平拆分/缩放内容卷
它允许你分配和并行操作的碎片(可能在多个节点上)从而提高性能/吞吐量
复制是重要的两个主要原因:
它以碎片/节点失败提供了高可用性。为此,需要注意的是,一个复制碎片不会分配在同一个节点作为原始/初级碎片,它是复制的重要。
它允许您扩展您的搜索量/吞吐量,因为搜索可以在所有副本上并行执行。
elasticsearch 的安装
安装前先安装jdk7 以上版本。
第一步下载 elastic search
打开终端输入命令
cd ~
curl -L -O https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/tar/elasticsearch/2.3.4/elasticsearch-2.3.4.tar.gz
第二步 解压安装 elasticsearch
mkdir elk
cd elk
mv ../elasticsearch-2.3.4.tar.gz ./
tar -xvf elasticsearch-2.3.4.tar.gz
ln -s elasticsearch-2.3.4 elasticsearch
第三步启动elasticsearch
cd elasticsearch/bin
./elasticsearch
Elasticsearch REST API
Elasticsearch提供了非常全面和强大的REST API,你可以使用你的集群互动。在API中可以做的一些事情如下:
检查群集、节点和索引的健康、状态和统计数据
管理群集、节点和索引数据和元数据
执行CRUD(创建,读取,更新和删除)和对你的索引搜索操作
执行高级搜索操作如分页、排序、过滤、脚本、聚合,和许多其他
集群健康 查询
curl 'localhost:9200/_cat/health?v'
我们要么得到绿色,黄色,或红色。
绿色意味着一切都是好的(集群是完全功能)
黄色意味着所有的数据是可用的,但一些副本尚未分配(集群是完全功能)
红色意味着一些数据是不可用的任何原因
集群所有节点 查询
curl 'localhost:9200/_cat/nodes?v'
集群中的所有索引 查询
curl 'localhost:9200/_cat/indices?v'
集群中创建索引
curl -XPUT 'localhost:9200/customer?pretty'
集群中为文档被索引
为了索引文件,我们必须在指数应该去告诉Elasticsearch的类型
让我们将一个简单的客户文档索引为“external”类型的customer索引,ID为1
curl -XPUT 'localhost:9200/customer/external/1?pretty' -d '
{
"name": "John Doe"
}'
注意:如果customer索引在此之前没有创建的话,elasticsearch 会隐式的创建customer索引的。
集群中检索索引文档
curl -XGET 'localhost:9200/customer/external/1?pretty'
集群中删除索引
curl -XDELETE 'localhost:9200/customer?pretty'
Elasticsearch 的命令格式
curl -X
集群中更新索引中的文档
curl -XPUT 'localhost:9200/customer/external/1?pretty' -d '
{
"name": "John Doe"
} '
curl -XPUT 'localhost:9200/customer/external/1?pretty' -d '
{
"name": "Jane Doe"
}'
注意: 类型和id必须一样,才是更新文档,否则是新增索引文档。
如果创建文档索引时不指定ID则
curl -XPOST 'localhost:9200/customer/external?pretty' -d '
{
"name": "Jane Doe"
}'
系统会随机一个ID给这个文档索引。
更新文档的字段值
//更新类型为external,索引为customer,ID为1的文档的name字段值
curl -XPOST 'localhost:9200/customer/external/1/_update?pretty' -d '
{
"doc": { "name": "Jane Doe" }
}'
//更新类型为external,索引为customer,ID为1的文档的name字段值,而且新增字段age,其值为20
curl -XPOST 'localhost:9200/customer/external/1/_update?pretty' -d '
{
"doc": { "name": "Jane Doe", "age": 20 }
}'
//调用调脚步去更改文档字段的值
curl -XPOST 'localhost:9200/customer/external/1/_update?pretty' -d '
{
"script" : "ctx._source.age += 5"
}'
注意:elasticsearch 版本1.4.3之后默认Groovy动态脚步关闭,要开启Groovy动态脚步需要在
config/elasticsearch.yml 添加2行代码
script.inline: true
script.indexed: true
更多脚步运行参考
https://www.elastic.co/guide/en/elasticsearch/reference/2.3/modules-scripting.html
集群删除文档
curl -XDELETE 'localhost:9200/customer/external/2?pretty'
集群批处理增删改文档(_bulk API)
//
curl -XPOST 'localhost:9200/customer/external/_bulk?pretty' -d '
{"index":{"_id":"1"}}
{"name": "John Doe" }
{"index":{"_id":"2"}}
{"name": "Jane Doe" }
'
更改id为1的文档的name字段值,删除ID为2的文档
curl -XPOST 'localhost:9200/customer/external/_bulk?pretty' -d '
{"update":{"_id":"1"}}
{"doc": { "name": "John Doe becomes Jane Doe" } }
{"delete":{"_id":"2"}}
'
批量API按顺序顺序执行所有操作。如果一个单一的行动失败了,它将继续处理剩余的行动后。当批量API返回时,它将为每个动作提供一个状态(以相同的顺序发送),以便检查特定的操作是否失败。
批量导入数据集,其中文件accounts.json在当前目录下。
curl -XPOST 'localhost:9200/bank/account/_bulk?pretty' --data-binary "@accounts.json"
查询API(Search API)
分2种查询方式
1 REST request URI(相当于http GET方法请求)
2 REST request body(相当于http POST方法请求)
方式1:
//返回索引为bank的所有文档
curl 'localhost:9200/bank/_search?q=*&pretty'
方式2:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match_all": {} }
}'
返回的响应参数:
took 所花费的时间
timed_out 搜索是否超时
_shards 搜索了多少个分片
hits 搜索结果
hits.total 搜索的文档总数
hits.hits
//搜索索引为bank的所有文档,但只返回第一个文档
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match_all": {} },
"size": 1
}'
注意:size默认值为10
//搜索索引为bank的所有文档,但返回的结果是从索引为10的开始及后面9个文档。(如果有9个)
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match_all": {} },
"from": 10,
"size": 10
}'
注意:from 默认为0
//搜索索引为bank的所有文档,但结果返回balance从大到小的前10个文档
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match_all": {} },
"sort": { "balance": { "order": "desc" } }
}'
//返回的结果文档的信息只包含2个字段,一个是account_number,另一个是balance
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match_all": {} },
"_source": ["account_number", "balance"]
}'
以上是全文档查询 match_all,下面的是基于文档的字段查询
//查询文档中account_number为20的文档。
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match": { "account_number": 20 } }
}'
//查询文档字段address中含有mill 或 lane的文档。
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match": { "address": "mill lane" } }
}'
curl -XPOST '192.168.9.90:9200/bank/_search?pretty' -d '
{
"query": { "match": { "address": "mill lane" } }
}'
curl -XPOST '192.168.9.90:9200/bank/_search?pretty' -d '
{
"query": { "match": { "email": "leelong lane" } }
}'
curl -XPOST '192.168.1.14:9200/index_hxjb_order/hxjborder/_search?pretty' -d '
{
"query": { "match": { "supplier_name": "测试 家博" } }
}'
查询文档字段address中含有mill 或含有lane的文档,这个是一个boolean查询,查询的条件满足至少一个是真时才是真。
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"should": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}'
//查询文档字段address中既含有mill 又含有lane的文档
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match_phrase": { "address": "mill lane" } }
}'
//查询文档字段address中既含有mill 又含有lane的文档,这个是一个boolean查询,查询的条件必须都满足时才是真。
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"must": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}'
//查询文档字段address中既不含有mill 又不含有lane的文档
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"must_not": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}'
响应参数中含有score字段,score值越高与查询的条件越符合。但是filter查询对score的计算没有影响。
//查询所有的文档,过滤条件balance的值在20000到30000
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"must": { "match_all": {} },
"filter": {
"range": {
"balance": {
"gte": 20000,
"lte": 30000
}
}
}
}
}
}'
//聚合查询 以字段state为组查询各个值的汇总结果
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"size": 0,
"aggs": {
"group_by_state": {
"terms": {
"field": "state"
}
}
}
}'
类似SQL
SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC
将年龄段分3组,每组在按性别分组,并求出每个年龄段中不同性别的工资平均值。
curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"size": 0,
"aggs": {
"group_by_age": {
"range": {
"field": "age",
"ranges": [
{
"from": 20,
"to": 30
},
{
"from": 30,
"to": 40
},
{
"from": 40,
"to": 50
}
]
},
"aggs": {
"group_by_gender": {
"terms": {
"field": "gender"
},
"aggs": {
"average_balance": {
"avg": {
"field": "balance"
}
}
}
}
}
}
}
}'
聚合主要分3种
metric aggregations
bucket aggregations
pipeline aggregations