前言
因为公司某位同事的离职,我需要接手原本由其负责的项目。其中包括包含了千万数据的中小学题库和题库搜索。为了保障后续能够高效完成这一部分功能的正常迭代。我不得不着手学习Elasticsearch的基本使用,进而产生了这一篇学习实录,不了解这一工具的同学或许也能通过本文获得些许帮助。
阅读之前请确认:
- 您明白什么是unix/linux命令行。
- 您确定了解什么是网络请求以及tcp/udp的相关知识,并在任意编程语言中实现过这些网络请求。
- 您了解
curl
命令的使用。 - 您了解
get
和put
请求,了解REST和RESTful——可以参考该链接文章《什么是RESTFUL?REST的请求方法有哪些,有什么区别?》。
正文
环境准备
JDK8
yum、apt、brew等包管理工具下载也可,通过源码编译安装也可,通过deb、.exe安装也可。
下载并启动ES6
我是mac,所以直接用brew下载就好了。
brew install elasticsearch
下载完成后直接输入命令启动。
elasticsearch
命令使用
健康状态检查
curl -XGET 'localhost:9200/_cat/health?v&pretty'
运行结果如下。
查看节点列表
curl -XGET 'localhost:9200/_cat/nodes?v&pretty'
查看索引列表
执行下述命令。
curl -XGET 'localhost:9200/_cat/indices?v&pretty'
如果没有索引就会只有一个表头,如下。
如果有索引就会是如下效果。
创建索引
创建一个名为『test_index』的索引,可以发起如下请求。
curl -XPUT 'localhost:9200/test_index&pretty'
然后可以通过上文中『查看索引列表』查看确认。执行效果如下。
添加文档doc
向上述创建的索引『test_index』插入一个id = 1
的doc,内容如下。
{
"content": "Test Data By Funco~~~"
}
则命令行如下。
curl -XPUT 'localhost:9200/test_index/doc/1?pretty&pretty' -H 'Content-Type: application/json' -d '{"content": "Test Data By Funco~~~"}'
则执行效果如下。
注意
- 如果向一个不存在的index添加一个doc,则该index将被创建,doc也会添加成功。
- 如果重复向同一id执行该命令,旧doc将直接被新doc简单替换。
- id不是必须的,如果不指定id,es将随机产生一个id作为索引。无论是否指定id,id都可在返回结果中获取,如上述运行图中的字段
_id
。
获取文档
这里获取刚刚添加的id = 1
的doc。
curl -XGET 'localhost:9200/test_index/doc/1?pretty&pretty'
执行效果如下。
删除索引
在上文中,我们提到,如果添加文档时,选择的索引不存在,则该索引会被添加。那么,现在如果我们希望将误操作添加的索引移除怎么办呢?可以执行如下命令,比如我们现在要删除一个名为customer
的索引。
curl -XDELETE 'localhost:9200/customer?pretty&pretty'
执行效果如下,且执行成功后,再次通过上述查看索引列表命令查看,会发现该索引已经不存在于列表中了。
修改文档
刚刚在『添加文档』一节中,提到新doc会将旧doc简单替换,但这时候,如果我们希望仅修改部分内容而非替换呢?
现在假设我们在索引test_index
中,存在如下id = 1 的 doc。
curl -XPOST 'localhost:9200/test_index/doc/1/_update?pretty&pretty' -H 'Content-Type: application/json' -d '{"doc":{"author": "funco"}}'
执行效果如下。注意使用POST提交,以及-d
中的doc
字段,对比修改前的doc、修改时提交的data
参数以及修改后的doc,你或许就明白了。
删除文档
这个没什么好讲的,提交REST DELETE操作,指定index下某个id指向的doc。比如,我要删除test_index中id = 1
的doc。可以执行如下命令。
curl -XDELETE 'localhost:9200/test_index/doc/1?pretty&pretty'
执行效果如下。可以看到,删除后,再次get该doc,返回结果的字段found
为false
。
批处理
批量插入文档
curl -XPOST 'localhost:9200/test_index/doc/_bulk?pretty&pretty' -H 'Content-Type: application/json' -d '
{"index":{"_id": 2}}
{"content":"test content2"}
{"index":{"_id": 3}}
{"content":"test content3"}
'
执行效果如下。
批量删除和修改
在接下来的案例中,我们可以了解到如何删除数据和修改数据,以及在一次请求中执行不同的操作。
首先,执行前确认存在id = 2
和 id = 3
的记录。
然后,执行下述命令。
curl -XPOST 'localhost:9200/test_index/doc/_bulk?pretty&pretty' -H 'Content-Type: application/json' -d '
{"update":{"_id": 2}}
{"doc":{"author":"funco"}}
{"delete":{"_id": 3}}
'
执行效果如下。
最后,再验证一下。可以确认执行成功。
搜索
已上一小节『批量删除和修改』为例,我们执行操作前后,向知道id =2 和id = 3的文档,都只能执行两次/<index>/doc/<id>
的GET
请求,如果我们想获取所有文档怎么办呢?假设我们现在要获取test_index
下的所有文档,可以执行下述命令。
curl -XGET 'localhost:9200/test_index/_search?q=*&pretty&pretty'
甚至我们可以增加get
参数sort=_id:asc
,实现搜索结果按照_id
字段升序排序。
curl -XGET 'localhost:9200/test_index/_search?q=*&sort=_id:asc&pretty&pretty'
需要注意的是,我们也可以将参数和前面的请求一样放在data中。效果和上例是一致的。这点在我们用代码发起请求时,保持风格一致的处理方式很有用。
curl -XGET 'localhost:9200/test_index/_search?pretty&pretty' -H 'Content-Type: application/json' -d '
{
"query": {"match_all":{}},
"sort": {"_id": "asc"}
}
'
默认的搜索结果是10,如果要搜索更多数据,需要通过
size
参数指定,关于搜索,我会另起一篇博客分享。