在上一篇的文章中,我们已经将es基本安装好了,并且kibana也已经安装好了,在本章中我们就利用kibana来使用es,
实践一下。主要的版本是
es7.9.3
kibana7.9.3
当然在使用es之前,我们需要新增一批数据进去,为了验证后面的用法而准备的数据。
本篇博客的思路基本就是按照es的基本概念来写的,用法上也是先从集群-->索引-->文档的基本的应用。
更复杂的应用我们会放到后续的博客中。
上一篇文章传送门
首先我们把示例数据下载下来,示例数据被我保存在了gitee中的helloes项目下:
https://gitee.com/xiezuozhen/hello-world/tree/master/HelloEs/src/test/resources/exampledata
可自行下载使用
我这里使用的是accounts.json,其中部分示例数据如下所示:
{"index":{"_id":"1"}}
{"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"}
{"index":{"_id":"6"}}
{"account_number":6,"balance":5686,"firstname":"Hattie","lastname":"Bond","age":36,"gender":"M","address":"671 Bristol Street","employer":"Netagy","email":"hattiebond@netagy.com","city":"Dante","state":"TN"}
{"index":{"_id":"13"}}
{"account_number":13,"balance":32838,"firstname":"Nanette","lastname":"Bates","age":28,"gender":"F","address":"789 Madison Street","employer":"Quility","email":"nanettebates@quility.com","city":"Nogal","state":"VA"}
{"index":{"_id":"18"}}
{"account_number":18,"balance":4180,"firstname":"Dale","lastname":"Adams","age":33,"gender":"M","address":"467 Hutchinson Court","employer":"Boink","email":"daleadams@boink.com","city":"Orick","state":"MD"}
{"index":{"_id":"20"}}
{"account_number":20,"balance":16418,"firstname":"Elinor","lastname":"Ratliff","age":36,"gender":"M","address":"282 Kings Place","employer":"Scentric","email":"elinorratliff@scentric.com","city":"Ribera","state":"WA"}
{"index":{"_id":"25"}}
{"account_number":25,"balance":40540,"firstname":"Virginia","lastname":"Ayala","age":39,"gender":"F","address":"171 Putnam Avenue","employer":"Filodyne","email":"virginiaayala@filodyne.com","city":"Nicholson","state":"PA"}
{"index":{"_id":"32"}}
{"account_number":32,"balance":48086,"firstname":"Dillard","lastname":"Mcpherson","age":34,"gender":"F","address":"702 Quentin Street","employer":"Quailcom","email":"dillardmcpherson@quailcom.com","city":"Veguita","state":"IN"}
{"index":{"_id":"37"}}
{"account_number":37,"balance":18612,"firstname":"Mcgee","lastname":"Mooney","age":39,"gender":"M","address":"826 Fillmore Place","employer":"Reversus","email":"mcgeemooney@reversus.com","city":"Tooleville","state":"OK"}
{"index":{"_id":"44"}}
{"account_number":44,"balance":34487,"firstname":"Aurelia","lastname":"Harding","age":37,"gender":"M","address":"502 Baycliff Terrace","employer":"Orbalix","email":"aureliaharding@orbalix.com","city":"Yardville","state":"DE"}
{"index":{"_id":"49"}}
{"account_number":49,"balance":29104,"firstname":"Fulton","lastname":"Holt","age":23,"gender":"F","address":"451 Humboldt Street","employer":"Anocha","email":"fultonholt@anocha.com","city":"Sunriver","state":"RI"}
{"index":{"_id":"51"}}
{"account_number":51,"balance":14097,"firstname":"Burton","lastname":"Meyers","age":31,"gender":"F","address":"334 River Street","employer":"Bezal","email":"burtonmeyers@bezal.com","city":"Jacksonburg","state":"MO"}
{"index":{"_id":"56"}}
{"account_number":56,"balance":14992,"firstname":"Josie","lastname":"Nelson","age":32,"gender":"M","address":"857 Tabor Court","employer":"Emtrac","email":"josienelson@emtrac.com","city":"Sunnyside","state":"UT"}
当我们拿到示例数据后,我们可以通过进入宿主进行导入,
curl -H 'Content-Type:application/x-ndjson' -XPOST '192.168.47.210:9200/bank/account/_bulk?pretty' --data-binary "@accounts.json"
这里需要将accounts.json最后留一个空行,才能成功。
也可以利用kibana的可视化工具导入,不过可视化导入我这里导入的数据有点问题,所以这里就不展示kibana可视化导入了。
现在数据准备完毕,我们可以开始应用了。
主要分为了两类,一类为_cat,一类为_cluster
我这里仅仅是列举了部分常用的用法,如果想要查看关于cat的其他的用法可以参考官方文档
https://www.elastic.co/guide/en/elasticsearch/reference/current/cat.html
GET /_cat/nodes?v&pretty #查看所有节点信息
GET /_cat/shards?v&pretty #查看各shard的详细情况
GET /_cat/master?v&pretty #查看master节点信息
GET /_cat/indices?v&pretty #查看集群中所有index的详细信息
GET /_cat/segments?v&pretty #查看各index的segment详细信息,包括segment名, 所属shard, 内存(磁盘)占用大小, 是否刷盘
GET /_cat/count?v&pretty #查看当前集群的doc数量
GET /_cat/recovery?v&pretty #查看集群内每个shard的recovery过程.调整replica。
GET /_cat/health?v&pretty #查看集群当前状态:红、黄、绿
GET /_cat/pending_tasks?v&pretty #查看当前集群的pending task,即挂起的任务
GET /_cat/aliases?v&pretty #查看集群中所有alias信息,路由配置等
GET /_cat/thread_pool?v&pretty #查看集群各节点内部不同类型的threadpool的统计信息,
GET /_cat/plugins?v&pretty #查看集群各个节点上的plugin信息
GET /_cat/fielddata?v&pretty #查看当前集群各个节点的fielddata内存使用情况
GET /_cat/nodeattrs?v&pretty #查看单节点的自定义属性
GET /_cat/repositories?v&pretty #输出集群中注册快照存储库
GET /_cat/templates?v&pretty #输出当前正在存在的模板信息
我选择几个在生产环境中用的比较多的进行讲解:
GET /_cat/nodes:查看所有的节点信息
ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
192.168.47.210 64 91 2 0.05 0.10 0.13 dilmrt * es3
192.168.47.210 58 91 2 0.05 0.10 0.13 dilmrt - es1
192.168.47.210 70 91 2 0.05 0.10 0.13 dilmrt - es2
heap.percent 堆内存占用百分比
ram.percent 内存占用百分比
cpu CPU占用百分比
master *表示节点是集群中的主节点
name 节点名
GET /_cat/aliases?v&pretty 查询所有的别名信息
alias index filter routing.index routing.search is_write_index
.kibana-event-log-7.9.3 .kibana-event-log-7.9.3-000001 - - - true
ilm-history-2 ilm-history-2-000001 - - - true
.kibana .kibana_1 - - - -
.security .security-7 - - - -
.kibana_task_manager .kibana_task_manager_1 - - - -
alias 索引的别名
index 索引名
routing.index 索引路由
routing.search 搜索路由
filter 过滤
别名是es中非常重要的一个功能。不仅生产中经常用到,而且面试里面也经常会提起
GET /_cat/indices?v&pretty
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open .security-7 eY2dGhuKRpKcrnW_1dcAHg 1 1 7 0 51kb 25.5kb
green open .kibana-event-log-7.9.3-000001 FR7mcABbTZOWS_rLSnmHPQ 1 1 2 0 21.8kb 10.9kb
green open .apm-custom-link Xwzboc0UTWaAxXIRBFm0jw 1 1 0 0 416b 208b
green open .kibana_task_manager_1 6rW9n3yJRuSqZGR44QjlGw 1 1 6 3741 1mb 588kb
green open .apm-agent-configuration aNXRDK5FR0q-ZNbwVx54XA 1 1 0 0 416b 208b
green open .async-search 1Q_H4j1URoucJXkurKelZA 1 1 0 1 6.6kb 3.3kb
green open .kibana_1 EjDRMq5iSEOK6QitQqO4QQ 1 1 74 14 20.9mb 10.4mb
green open account LbMvFKxOR3mjfT9rflN7JA 1 1 1999 0 743kb 371.5kb
health 索引的健康状态
index 索引名
pri 索引主分片数量
rep 索引复制分片 数
store.size 索引主分片 复制分片 总占用存储空间
pri.store.size 索引总占用空间, 不计算复制分片 占用空间
还有其他的用法就不一一列举了,如果想查询更详细的信息自己可以翻阅官方文档
其实_cluster和_cat的用法差不多,返回的信息要比_cat详细的多,_cat一般是查看集群的相关信息,_cluster不仅可以查看,而且还可以对集群进行操作。
主要的命令有:
GET _cluster/health #查看集群健康状态接口
GET _cluster/state #查看集群状况接口
GET _cluster/stats #查看集群统计信息接口
GET _cluster/pending_tasks #查看集群挂起的任务接口
POST _cluster/reroute #集群重新路由操作(这个操作一般是在分片失败时使用,可以使用此命令重新尝试分片)
PUT _cluster/settings #更新集群设置
GET _nodes/stats #节点状态
GET _nodes #节点信息
GET _nodes/hot_threads #节点的热线程
GET nodes/_master/_shutdown #关闭节点
这里详细列举其中几个即可:
GET _cluster/health
{
"cluster_name" : "elasticsearch-cluster",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 3,
"number_of_data_nodes" : 3,
"active_primary_shards" : 9,
"active_shards" : 18,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 100.0
}
status:es集群状态
green:所有的主分片和副本父分片都已分配,集群100%可用。
yellow:所有的主分片已经分片,但至少还有一个副本分片是缺失的。不会有数据丢失,所以搜索结果依然是完整的。
不过高可用性在某种程度上被弱化。如果更多的分片消失,就会丢数据。
red:至少一个主分片(以及它的全部副本)都在丢失中。搜索只能返回部分数据,而分配到这个分片的写入请求会返回一个异常。
timed_out:是否超时
number_of_nodes :节点数
number_of_data_nodes:数据节点数
active_primary_shards:集群中所有索引的主分配数
active_shards:集群中所有索引的分片数
relocating_shards:当前正在节点间迁移的分片,该值在正常情况下为0,但在ES集群有节点加入或移除时,集群会发现分片分布不均衡,便会开始进行分片迁移。
initializing_shards:初始化中的分片数。往往在分片刚被创建或节点重启时,会经历短暂的initializing状态。
unassigned_shards:未分配的分片数。表示集群中存在分片但实际又找不到分片,常见于存在未分配的副本,如集群中有1个节点,有一个索引有5个分片1个副本,由于ES的灾备原则,副本分片不能与主分配保存在同一个节点中,那么就会有5个副本分片处于未分配状态。
GET _cluster/state
{
"cluster_name" : "elasticsearch-cluster",
"cluster_uuid" : "uY2HW2E1S4m_Y2N5YSBeJQ",
"version" : 492,
"state_uuid" : "sksdPfrxSDKBZTMWJBTTRg",
"master_node" : "jW8PbSdhTOOpESX13DRBJQ",
"blocks" : { },
"nodes" : {***},
"metadata" : {***},
"routing_table" : {***},
"routing_nodes" : {}
}
由于数据量比较大,所以我这里仅仅是把其中重要的几部分罗列出来了
nodes:节点
metadata:主要是元数据信息,包括集群元信息和索引元信息
routing_table:路由表
routing_nodes:路由节点
前面的基本都是对集群的查询,接下来我们学习一下关于索引的增删改查。
DELETE bank 表示删除bank索引
当然还可以批量删除
DELETE bank*就是将以bank开头的索引全部删除
如代码所示,我们新增一个banks索引。
PUT /banks/
{
"aliases" : { },
"mappings" : {
"properties" : {
"account_number" : {
"type" : "long"
},
"address" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"age" : {
"type" : "long"
},
"balance" : {
"type" : "long"
},
"city" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"email" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"employer" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"firstname" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"gender" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"lastname" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"state" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
},
"settings" : {
"index" : {
"number_of_shards" : "1",
"number_of_replicas" : "1"
}
}
}
由于在搜索引擎中,单纯对索引的修改,一般是先删除原来的索引,然后重建索引。
GET bank
查询索引的相关信息
返回结果:
{
"bank" : {
"aliases" : { },
"mappings" : {
"properties" : {
"account_number" : {
"type" : "long"
},
"address" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"age" : {
"type" : "long"
},
"balance" : {
"type" : "long"
},
"city" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"email" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"employer" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"firstname" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"gender" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"lastname" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"state" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
},
"settings" : {
"index" : {
"creation_date" : "1679827093469",
"number_of_shards" : "1",
"number_of_replicas" : "1",
"uuid" : "FbFyX5TdRGC88ZlbvnemmQ",
"version" : {
"created" : "7090399"
},
"provided_name" : "bank"
}
}
}
}
GET bank/_doc/1
返回结果:
{
"_index" : "bank",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_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"
}
}
DELETE bank/_doc/1
返回结果:
{
"_index" : "bank",
"_type" : "_doc",
"_id" : "1",
"_version" : 2,
"result" : "deleted",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 1000,
"_primary_term" : 1
}
PUT bank/_doc/1
{
"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"
}
返回结果:
{
"_index" : "bank",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 1001,
"_primary_term" : 1
}
PUT bank/_doc/1
{
"account_number" : 1,
"balance" : 39225,
"firstname" : "Amber_xzz",
"lastname" : "Duke",
"age" : 32,
"gender" : "M",
"address" : "880 Holmes Lane",
"employer" : "Pyrami",
"email" : "amberduke@pyrami.com",
"city" : "Brogan",
"state" : "IL"
}
我们将firstname=Amber修改为firstname=Amber_xzz,然后提交
返回结果为:
{
"_index" : "bank",
"_type" : "_doc",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 1002,
"_primary_term" : 1
}
其实kibana还有一个比较好用的地方,就是如下图所示的:

当我们对于某些查询的用法不是很了解时,我们可以通过图中所示的功能,直接定位到对应的详细文档,相当便捷。后续的很多的查询功能我不清楚时,也是通过这个文档来查看的。
我们这里仅仅是一些简单的使用,后续博客还会有很多关于查询的功能的使用。敬请期待…
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po