背景
公司在做一个app,里面涉及到了大量的文章搜索,如果按照传统的mysql去完成,虽然可以很容易的实现,但是性能方面却很力不从心,要知道mysql对like查询支持不好,如果数据量一大,很容易造成全表扫描,十分影响用户体验。
有个解决方案,elasticsearch可以解决这个问题。
Elasticsearch介绍
Elasticsearch 是一个开源的搜索引擎,建立在一个全文搜索引擎库 Apache Lucene™ 基础之上。 Lucene 可以说是当下最先进、高性能、全功能的搜索引擎库—无论是开源还是私有。
但是 Lucene 仅仅只是一个库。为了充分发挥其功能,你需要使用 Java 并将 Lucene 直接集成到应用程序中。 更糟糕的是,您可能需要获得信息检索学位才能了解其工作原理。Lucene 非常 复杂。
Elasticsearch 也是使用 Java 编写的,它的内部使用 Lucene 做索引与搜索,但是它的目的是使全文检索变得简单, 通过隐藏 Lucene 的复杂性,取而代之的提供一套简单一致的 RESTful API。
Elasticsearch 更像是个java服务,通过提供的restful api走http协议来完成通信。但是每次http通信都会tcp三次握手,所以一般用没什么问题,如果想追求高性能,最好还是用官方提供的REST High Level Client(随附maven下载地址链接)java客户端去调用,这个客户端封装了很多功能,做了类似连接池的功能,用来解决集群请求,tcp三次握手时间占用等问题。
地址
官网最新版本下载地址:https://www.elastic.co/cn/downloads/
官网各版本文档(含教程)介绍地址:https://www.elastic.co/guide/en/elasticsearch/reference/index.html
中文教程(版本比较老,建议看上面的英文教程):Elasticsearch: 权威指南
上面有很详细的各版本的安装使用方式,支持linux、mac os、windows,下面总结了一些入门常用用法,更详细的可以去官网看一下。
安装
去官网下载安装包,解压后进入bin目录运行elasticsearch文件就可以运行了,因为是java做的,依赖jdk,我电脑安装的是jdk8,以linux为例(截止发文,最新版是7.9.0)
下载下来安装包以后解压
tar -zxvf elasticsearch-7.9.0-linux-x86_64.tar.gz
cd elasticsearch-7.9.0/bin
./elasticsearch
注意不能用root用户运行,否则报错
启动成功默认9200端口用postman或者curl命令行get请求,下图可以看到端口信息

下面总结了一些常用用法,本文最后还有REST High Level Client的演示用法:
_index:存储位置,类似数据库名称
_type:存储type名称,类似表名(在新版中elasticsearch默认_doc的名字,不建议自定义)
_id:唯一id
1.直接访问端口返回基本信息
GET http://172.26.239.235:9200
返回json:
{
"name": "zhaohy-PC",
"cluster_name": "elasticsearch",
"cluster_uuid": "d8LySvHoTret1dNjoB55tw",
"version": {
"number": "7.9.0",
"build_flavor": "default",
"build_type": "tar",
"build_hash": "a479a2a7fce0389512d6a9361301708b92dff667",
"build_date": "2020-08-11T21:36:48.204330Z",
"build_snapshot": false,
"lucene_version": "8.6.0",
"minimum_wire_compatibility_version": "6.8.0",
"minimum_index_compatibility_version": "6.0.0-beta1"
},
"tagline": "You Know, for Search"
}
2.计算集群中文档的数量
GET http://172.26.239.235:9200/_count?pretty
{
"query": {
"match_all": {}
}
}
效果如图:

以下的效果图会做省略处理
3.新增一个文档
PUT http://172.26.239.235:9200/oneapp_test/t_oneapp_question/1
{
"id":"2",
"question_id":"2020000010804111403",
"uuid":"1596443685294289232",
"question_type_id":"1",
"question_content":"车联网里面最常用的远控空调是如何运作的?需要先启动发动机吗?",
"answer_content":"远控空调需要先冷启动发动机,通过后台发送指令唤醒TCU,TCU唤醒后接收到指令则发出启动发动机信号,等待发动机启动成功后反馈结果到TCU,然后TCU通过XX信号反馈结果给到APP,在APP界面上反馈结果。",
"img_path":"",
"location_info":"花城大道8号",
"is_show":"1",
"is_answer":"1",
"is_top":"0",
"like_count":"0",
"dislike_count":"0",
"read_count":"2",
"comment_count":"0",
"create_time":"2020-08-04 11:14:07.0",
"answer_time":"2020-08-04 11:30:01.0",
"update_time":"2020-08-04 11:30:01.0",
"share_count":"",
"score":99
}
返回json:
{
"_index": "oneapp_test",
"_type": "t_oneapp_question",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 2,
"_primary_term": 1
}
4.查询一个文档
GET http://172.26.239.235:9200/oneapp_test/t_oneapp_question/2
返回json:
{
"_index": "oneapp_test",
"_type": "t_oneapp_question",
"_id": "2",
"_version": 1,
"_seq_no": 0,
"_primary_term": 1,
"found": true,
"_source": {
"id": "2",
"question_id": "2020000010804111403",
"uuid": "1596443685294289232",
"question_type_id": "1",
"question_content": "车联网里面最常用的远控空调是如何运作的?需要先启动发动机吗?",
"answer_content": "远控空调需要先冷启动发动机,通过后台发送指令唤醒TCU,TCU唤醒后接收到指令则发出启动发动机信号,等待发动机启动成功后反馈结果到TCU,然后TCU通过XX信号反馈结果给到APP,在APP界面上反馈结果。",
"img_path": "",
"location_info": "花城大道8号",
"is_show": "1",
"is_answer": "1",
"is_top": "0",
"like_count": "0",
"dislike_count": "0",
"read_count": "2",
"comment_count": "0",
"create_time": "2020-08-04 11:14:07.0",
"answer_time": "2020-08-04 11:30:01.0",
"update_time": "2020-08-04 11:30:01.0",
"share_count": ""
}
}
5.删除一个文档
DELETE http://172.26.239.235:9200/oneapp_test/t_oneapp_question/1
返回json:
{
"_index": "oneapp_test",
"_type": "t_oneapp_question",
"_id": "1",
"_version": 2,
"result": "deleted",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 3,
"_primary_term": 1
}
6.查询表中所有文档
GET http://172.26.239.235:9200/oneapp_test/t_oneapp_question/_search
返回json:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": "oneapp_test",
"_type": "t_oneapp_question",
"_id": "2",
"_score": 1.0,
"_source": {
"id": "2",
"question_id": "2020000010804111403",
"uuid": "1596443685294289232",
"question_type_id": "1",
"question_content": "车联网里面最常用的远控空调是如何运作的?需要先启动发动机吗?",
"answer_content": "远控空调需要先冷启动发动机,通过后台发送指令唤醒TCU,TCU唤醒后接收到指令则发出启动发动机信号,等待发动机启动成功后反馈结果到TCU,然后TCU通过XX信号反馈结果给到APP,在APP界面上反馈结果。",
"img_path": "",
"location_info": "花城大道8号",
"is_show": "1",
"is_answer": "1",
"is_top": "0",
"like_count": "0",
"dislike_count": "0",
"read_count": "2",
"comment_count": "0",
"create_time": "2020-08-04 11:14:07.0",
"answer_time": "2020-08-04 11:30:01.0",
"update_time": "2020-08-04 11:30:01.0",
"share_count": "",
"score": 99
}
}
]
}
}
7.轻量检索
GET http://172.26.239.235:9200/oneapp_test/t_oneapp_question/_search?q=question_id: 2020000010804111403
返回json:
{
"took": 22,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.2876821,
"hits": [
{
"_index": "oneapp_test",
"_type": "t_oneapp_question",
"_id": "2",
"_score": 0.2876821,
"_source": {
"id": "2",
"question_id": "2020000010804111403",
"uuid": "1596443685294289232",
"question_type_id": "1",
"question_content": "车联网里面最常用的远控空调是如何运作的?需要先启动发动机吗?",
"answer_content": "远控空调需要先冷启动发动机,通过后台发送指令唤醒TCU,TCU唤醒后接收到指令则发出启动发动机信号,等待发动机启动成功后反馈结果到TCU,然后TCU通过XX信号反馈结果给到APP,在APP界面上反馈结果。",
"img_path": "",
"location_info": "花城大道8号",
"is_show": "1",
"is_answer": "1",
"is_top": "0",
"like_count": "0",
"dislike_count": "0",
"read_count": "2",
"comment_count": "0",
"create_time": "2020-08-04 11:14:07.0",
"answer_time": "2020-08-04 11:30:01.0",
"update_time": "2020-08-04 11:30:01.0",
"share_count": ""
}
}
]
}
}
8.查询表达式轻量检索
GET http://172.26.239.235:9200/oneapp_test/t_oneapp_question/_search
{
"query" : {
"match" : {
"question_id": "2020000010804111403"
}
}
}
返回json:
{
"took": 0,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.2876821,
"hits": [
{
"_index": "oneapp_test",
"_type": "t_oneapp_question",
"_id": "2",
"_score": 0.2876821,
"_source": {
"id": "2",
"question_id": "2020000010804111403",
"uuid": "1596443685294289232",
"question_type_id": "1",
"question_content": "车联网里面最常用的远控空调是如何运作的?需要先启动发动机吗?",
"answer_content": "远控空调需要先冷启动发动机,通过后台发送指令唤醒TCU,TCU唤醒后接收到指令则发出启动发动机信号,等待发动机启动成功后反馈结果到TCU,然后TCU通过XX信号反馈结果给到APP,在APP界面上反馈结果。",
"img_path": "",
"location_info": "花城大道8号",
"is_show": "1",
"is_answer": "1",
"is_top": "0",
"like_count": "0",
"dislike_count": "0",
"read_count": "2",
"comment_count": "0",
"create_time": "2020-08-04 11:14:07.0",
"answer_time": "2020-08-04 11:30:01.0",
"update_time": "2020-08-04 11:30:01.0",
"share_count": ""
}
}
]
}
}
9.过滤搜索
GET http://172.26.239.235:9200/oneapp_test/t_oneapp_question/_search
{
"query" : {
"bool": {
"must": {
"match" : {
"is_show": "1"
}
},
"filter": {
"range" : {
"read_count" : { "gt" : 3 }
}
}
}
}
}
返回json:
{
"took": 7,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 0,
"relation": "eq"
},
"max_score": null,
"hits": []
}
}
10.全文搜索
GET http://172.26.239.235:9200/oneapp_test/t_oneapp_question/_search
{
"query" : {
"match" : {
"question_content" : "车联网"
}
}
}
返回json:
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.8630463,
"hits": [
{
"_index": "oneapp_test",
"_type": "t_oneapp_question",
"_id": "2",
"_score": 0.8630463,
"_source": {
"id": "2",
"question_id": "2020000010804111403",
"uuid": "1596443685294289232",
"question_type_id": "1",
"question_content": "车联网里面最常用的远控空调是如何运作的?需要先启动发动机吗?",
"answer_content": "远控空调需要先冷启动发动机,通过后台发送指令唤醒TCU,TCU唤醒后接收到指令则发出启动发动机信号,等待发动机启动成功后反馈结果到TCU,然后TCU通过XX信号反馈结果给到APP,在APP界面上反馈结果。",
"img_path": "",
"location_info": "花城大道8号",
"is_show": "1",
"is_answer": "1",
"is_top": "0",
"like_count": "0",
"dislike_count": "0",
"read_count": "2",
"comment_count": "0",
"create_time": "2020-08-04 11:14:07.0",
"answer_time": "2020-08-04 11:30:01.0",
"update_time": "2020-08-04 11:30:01.0",
"share_count": ""
}
}
]
}
}
11.短语搜索
GET http://172.26.239.235:9200/oneapp_test/t_oneapp_question/_search
{
"query" : {
"match_phrase" : {
"question_content" : "车联网"
}
}
}
返回json:
{
"took": 0,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.8630463,
"hits": [
{
"_index": "oneapp_test",
"_type": "t_oneapp_question",
"_id": "2",
"_score": 0.8630463,
"_source": {
"id": "2",
"question_id": "2020000010804111403",
"uuid": "1596443685294289232",
"question_type_id": "1",
"question_content": "车联网里面最常用的远控空调是如何运作的?需要先启动发动机吗?",
"answer_content": "远控空调需要先冷启动发动机,通过后台发送指令唤醒TCU,TCU唤醒后接收到指令则发出启动发动机信号,等待发动机启动成功后反馈结果到TCU,然后TCU通过XX信号反馈结果给到APP,在APP界面上反馈结果。",
"img_path": "",
"location_info": "花城大道8号",
"is_show": "1",
"is_answer": "1",
"is_top": "0",
"like_count": "0",
"dislike_count": "0",
"read_count": "2",
"comment_count": "0",
"create_time": "2020-08-04 11:14:07.0",
"answer_time": "2020-08-04 11:30:01.0",
"update_time": "2020-08-04 11:30:01.0",
"share_count": ""
}
}
]
}
}
12.高亮搜索
GET http://172.26.239.235:9200/oneapp_test/t_oneapp_question/_search
{
"query" : {
"match_phrase" : {
"question_content" : "发动机"
}
},
"highlight": {
"fields" : {
"question_content":{}
}
}
}
返回json:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.8630463,
"hits": [
{
"_index": "oneapp_test",
"_type": "t_oneapp_question",
"_id": "2",
"_score": 0.8630463,
"_source": {
"id": "2",
"question_id": "2020000010804111403",
"uuid": "1596443685294289232",
"question_type_id": "1",
"question_content": "车联网里面最常用的远控空调是如何运作的?需要先启动发动机吗?",
"answer_content": "远控空调需要先冷启动发动机,通过后台发送指令唤醒TCU,TCU唤醒后接收到指令则发出启动发动机信号,等待发动机启动成功后反馈结果到TCU,然后TCU通过XX信号反馈结果给到APP,在APP界面上反馈结果。",
"img_path": "",
"location_info": "花城大道8号",
"is_show": "1",
"is_answer": "1",
"is_top": "0",
"like_count": "0",
"dislike_count": "0",
"read_count": "2",
"comment_count": "0",
"create_time": "2020-08-04 11:14:07.0",
"answer_time": "2020-08-04 11:30:01.0",
"update_time": "2020-08-04 11:30:01.0",
"share_count": ""
},
"highlight": {
"question_content": [
"需要先启动<em>发</em><em>动</em><em>机</em>吗?"
]
}
}
]
}
}
13.多个字段高亮搜索
GET http://172.26.239.235:9200/oneapp_test/t_oneapp_question/_search
{
"query": {
"bool": {
"should": [
{
"match_phrase": {
"question_content": "发动机"
}
},
{
"match_phrase": {
"answer_content": "发动机"
}
}
]
}
},
"highlight": {
"fields" : {
"question_content":{},
"answer_content":{}
}
}
}
返回json:
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 2.2298481,
"hits": [
{
"_index": "oneapp_test",
"_type": "t_oneapp_question",
"_id": "2",
"_score": 2.2298481,
"_source": {
"id": "2",
"question_id": "2020000010804111403",
"uuid": "1596443685294289232",
"question_type_id": "1",
"question_content": "车联网里面最常用的远控空调是如何运作的?需要先启动发动机吗?",
"answer_content": "远控空调需要先冷启动发动机,通过后台发送指令唤醒TCU,TCU唤醒后接收到指令则发出启动发动机信号,等待发动机启动成功后反馈结果到TCU,然后TCU通过XX信号反馈结果给到APP,在APP界面上反馈结果。",
"img_path": "",
"location_info": "花城大道8号",
"is_show": "1",
"is_answer": "1",
"is_top": "0",
"like_count": "0",
"dislike_count": "0",
"read_count": "2",
"comment_count": "0",
"create_time": "2020-08-04 11:14:07.0",
"answer_time": "2020-08-04 11:30:01.0",
"update_time": "2020-08-04 11:30:01.0",
"share_count": ""
},
"highlight": {
"answer_content": [
"远控空调需要先冷启动<em>发</em><em>动</em><em>机</em>,通过后台发送指令唤醒TCU,TCU唤醒后接收到指令则发出启动<em>发</em><em>动</em><em>机</em>信号,等待<em>发</em><em>动</em><em>机</em>启动成功后反馈结果到TCU,然后TCU通过XX信号反馈结果给到APP,在APP界面上反馈结果"
],
"question_content": [
"需要先启动<em>发</em><em>动</em><em>机</em>吗?"
]
}
}
]
}
}
14.搜索所有(默认返回前十条)
GET http://172.26.239.235:9200/_search
返回json:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 9,
"successful": 9,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 39,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": ".kibana_1",
"_type": "_doc",
"_id": "space:default",
"_score": 1,
"_source": {
"space": {
"name": "默认值",
"description": "这是您的默认工作区!",
"color": "#00bfb3",
"disabledFeatures": [],
"_reserved": true
},
"type": "space",
"references": [],
"migrationVersion": {
"space": "6.6.0"
},
"updated_at": "2020-07-31T02:13:38.972Z"
}
},
{
"_index": ".kibana_1",
"_type": "_doc",
"_id": "config:7.6.2",
"_score": 1,
"_source": {
"config": {
"buildNum": 29199
},
"type": "config",
"references": [],
"updated_at": "2020-07-31T02:13:48.850Z"
}
}
...
]
}
}
15.搜索自定义返回条数
GET http://172.26.239.235:9200/_search?size=3
返回json:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 9,
"successful": 9,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 40,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": ".kibana_1",
"_type": "_doc",
"_id": "space:default",
"_score": 1.0,
"_source": {
"space": {
"name": "默认值",
"description": "这是您的默认工作区!",
"color": "#00bfb3",
"disabledFeatures": [],
"_reserved": true
},
"type": "space",
"references": [],
"migrationVersion": {
"space": "6.6.0"
},
"updated_at": "2020-07-31T02:13:38.972Z"
}
},
{
"_index": ".kibana_1",
"_type": "_doc",
"_id": "config:7.6.2",
"_score": 1.0,
"_source": {
"config": {
"buildNum": 29199
},
"type": "config",
"references": [],
"updated_at": "2020-07-31T02:13:48.850Z"
}
},
{
"_index": ".kibana_1",
"_type": "_doc",
"_id": "telemetry:telemetry",
"_score": 1.0,
"_source": {
"telemetry": {
"userHasSeenNotice": true
},
"type": "telemetry",
"references": [],
"updated_at": "2020-07-31T02:14:01.524Z"
}
}
]
}
}
16.分页搜索
GET http://172.26.239.235:9200/_search?size=3&from=33
返回json:
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 9,
"successful": 9,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 40,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": ".kibana_task_manager_1",
"_type": "_doc",
"_id": "task:Lens-lens_telemetry",
"_score": 1.0,
"_source": {
"migrationVersion": {
"task": "7.6.0"
},
"task": {
"taskType": "lens_telemetry",
"retryAt": null,
"runAt": "2020-08-19T16:00:00.000Z",
"startedAt": null,
"state": "{\"runs\":20,\"byDate\":{},\"suggestionsByDate\":{},\"saved\":{\"saved_30_days\":{},\"saved_overall_total\":0,\"saved_30_days_total\":0,\"saved_90_days_total\":0}}",
"params": "{}",
"ownerId": null,
"scheduledAt": "2020-07-31T02:13:42.298Z",
"attempts": 0,
"status": "idle"
},
"references": [],
"updated_at": "2020-08-18T16:00:00.349Z",
"type": "task"
}
},
{
"_index": "index",
"_type": "type",
"_id": "1",
"_score": 1.0,
"_source": {
"name": "here",
"age": 12
}
},
{
"_index": "oneapp_test",
"_type": "t_oneapp_question",
"_id": "2",
"_score": 1.0,
"_source": {
"id": "2",
"question_id": "2020000010804111403",
"uuid": "1596443685294289232",
"question_type_id": "1",
"question_content": "车联网里面最常用的远控空调是如何运作的?需要先启动发动机吗?",
"answer_content": "远控空调需要先冷启动发动机,通过后台发送指令唤醒TCU,TCU唤醒后接收到指令则发出启动发动机信号,等待发动机启动成功后反馈结果到TCU,然后TCU通过XX信号反馈结果给到APP,在APP界面上反馈结果。",
"img_path": "",
"location_info": "花城大道8号",
"is_show": "1",
"is_answer": "1",
"is_top": "0",
"like_count": "0",
"dislike_count": "0",
"read_count": "2",
"comment_count": "0",
"create_time": "2020-08-04 11:14:07.0",
"answer_time": "2020-08-04 11:30:01.0",
"update_time": "2020-08-04 11:30:01.0",
"share_count": "",
"score": 99
}
}
]
}
}
17.给字段加属性方便聚合或排序
PUT http://172.26.239.235:9200/oneapp_test/_mapping?pretty
{
"properties": {
"create_time": {
"type": "text",
"fielddata": true
},
"is_top": {
"type": "text",
"fielddata": true
},
"read_count": {
"type": "text",
"fielddata": true
}
}
}
返回json:
{
"acknowledged": true
}
18.单字段排序
GET http://172.26.239.235:9200/oneapp_test/t_oneapp_question/_search
{
"query" : {
"bool" : {
"filter" : { "term" : { "question_type_id" : "1" }}
}
},
"sort": { "create_time": { "order": "desc" }}
}
返回json:
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": null,
"hits": [
{
"_index": "oneapp_test",
"_type": "t_oneapp_question",
"_id": "2",
"_score": null,
"_source": {
"id": "2",
"question_id": "2020000010804111403",
"uuid": "1596443685294289232",
"question_type_id": "1",
"question_content": "车联网里面最常用的远控空调是如何运作的?需要先启动发动机吗?",
"answer_content": "远控空调需要先冷启动发动机,通过后台发送指令唤醒TCU,TCU唤醒后接收到指令则发出启动发动机信号,等待发动机启动成功后反馈结果到TCU,然后TCU通过XX信号反馈结果给到APP,在APP界面上反馈结果。",
"img_path": "",
"location_info": "花城大道8号",
"is_show": "1",
"is_answer": "1",
"is_top": "0",
"like_count": "0",
"dislike_count": "0",
"read_count": "2",
"comment_count": "0",
"create_time": "2020-08-04 11:14:07.0",
"answer_time": "2020-08-04 11:30:01.0",
"update_time": "2020-08-04 11:30:01.0",
"share_count": ""
},
"sort": [
"2020"
]
}
]
}
}
19.多字段排序
GET http://172.26.239.235:9200/oneapp_test/t_oneapp_question/_search
{
"query" : {
"bool" : {
"must": { "match": { "question_content": "发动机" }},
"filter" : { "term" : { "question_type_id" : "1" }}
}
},
"sort": [
{ "is_top": { "order": "desc" }},
{ "create_time": { "order": "desc" }}
]
}
返回json:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": null,
"hits": [
{
"_index": "oneapp_test",
"_type": "t_oneapp_question",
"_id": "2",
"_score": null,
"_source": {
"id": "2",
"question_id": "2020000010804111403",
"uuid": "1596443685294289232",
"question_type_id": "1",
"question_content": "车联网里面最常用的远控空调是如何运作的?需要先启动发动机吗?",
"answer_content": "远控空调需要先冷启动发动机,通过后台发送指令唤醒TCU,TCU唤醒后接收到指令则发出启动发动机信号,等待发动机启动成功后反馈结果到TCU,然后TCU通过XX信号反馈结果给到APP,在APP界面上反馈结果。",
"img_path": "",
"location_info": "花城大道8号",
"is_show": "1",
"is_answer": "1",
"is_top": "0",
"like_count": "0",
"dislike_count": "0",
"read_count": "2",
"comment_count": "0",
"create_time": "2020-08-04 11:14:07.0",
"answer_time": "2020-08-04 11:30:01.0",
"update_time": "2020-08-04 11:30:01.0",
"share_count": ""
},
"sort": [
"0",
"2020"
]
}
]
}
}
20.聚合(类似groupby)
GET http://172.26.239.235:9200/oneapp_test/t_oneapp_question/_search
{
"aggs": {
"all_is_top": {
"terms": { "field": "is_top" }
}
}
}
返回json:
{
"took": 0,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": "oneapp_test",
"_type": "t_oneapp_question",
"_id": "2",
"_score": 1.0,
"_source": {
"id": "2",
"question_id": "2020000010804111403",
"uuid": "1596443685294289232",
"question_type_id": "1",
"question_content": "车联网里面最常用的远控空调是如何运作的?需要先启动发动机吗?",
"answer_content": "远控空调需要先冷启动发动机,通过后台发送指令唤醒TCU,TCU唤醒后接收到指令则发出启动发动机信号,等待发动机启动成功后反馈结果到TCU,然后TCU通过XX信号反馈结果给到APP,在APP界面上反馈结果。",
"img_path": "",
"location_info": "花城大道8号",
"is_show": "1",
"is_answer": "1",
"is_top": "0",
"like_count": "0",
"dislike_count": "0",
"read_count": "2",
"comment_count": "0",
"create_time": "2020-08-04 11:14:07.0",
"answer_time": "2020-08-04 11:30:01.0",
"update_time": "2020-08-04 11:30:01.0",
"share_count": ""
}
}
]
},
"aggregations": {
"all_is_top": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "0",
"doc_count": 1
}
]
}
}
}
21.先查询再聚合
GET http://172.26.239.235:9200/oneapp_test/t_oneapp_question/_search
{
"query": {
"match": {
"question_content": "发动机"
}
},
"aggs": {
"all_is_top": {
"terms": {
"field": "is_top"
}
}
}
}
返回json:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.970927,
"hits": [
{
"_index": "oneapp_test",
"_type": "t_oneapp_question",
"_id": "2",
"_score": 0.970927,
"_source": {
"id": "2",
"question_id": "2020000010804111403",
"uuid": "1596443685294289232",
"question_type_id": "1",
"question_content": "车联网里面最常用的远控空调是如何运作的?需要先启动发动机吗?",
"answer_content": "远控空调需要先冷启动发动机,通过后台发送指令唤醒TCU,TCU唤醒后接收到指令则发出启动发动机信号,等待发动机启动成功后反馈结果到TCU,然后TCU通过XX信号反馈结果给到APP,在APP界面上反馈结果。",
"img_path": "",
"location_info": "花城大道8号",
"is_show": "1",
"is_answer": "1",
"is_top": "0",
"like_count": "0",
"dislike_count": "0",
"read_count": "2",
"comment_count": "0",
"create_time": "2020-08-04 11:14:07.0",
"answer_time": "2020-08-04 11:30:01.0",
"update_time": "2020-08-04 11:30:01.0",
"share_count": ""
}
}
]
},
"aggregations": {
"all_is_top": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "0",
"doc_count": 1
}
]
}
}
}
REST High Level Client演示用法
新建HighLevelRestClient类
package com.ly.mp.publicProj.common;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
public class HighLevelRestClient {
private static final Logger LOGGER = LoggerFactory.getLogger(HighLevelRestClient.class);
private static final String INDEX_NAME = "oneapp_test";
private static RestHighLevelClient client;
static {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("example", "WnhmUwjU"));
RestClientBuilder builder = RestClient.builder(new HttpHost("172.26.239.235", 9200, "http"))
.setFailureListener(new RestClient.FailureListener() { // 连接失败策略
public void onFailure(HttpHost host) {
LOGGER.error("init client error, host:{}", host);
}
})
// .setMaxRetryTimeoutMillis(10000) // 超时时间
.setHttpClientConfigCallback(new HttpClientConfigCallback() { // 认证
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
});
client = new RestHighLevelClient(builder);
}
/**
* 新增或者更新
*
* @param indexName
* @param id
* @param jsonString
* @return
*/
public boolean indexById(String indexName, String id, String jsonString) {
IndexRequest request = new IndexRequest(indexName);
request.id(id);
request.source(jsonString, XContentType.JSON);
IndexResponse response = null;
try {
response = client.index(request, RequestOptions.DEFAULT);
if (response.status().getStatus() == HttpStatus.SC_CREATED
|| response.status().getStatus() == HttpStatus.SC_OK) {
LOGGER.info("index success");
return true;
} else {
LOGGER.error("index error : {}", response.toString());
return false;
}
} catch (IOException e) {
LOGGER.error("系统异常", e);
return false;
}
}
/**
* 删除
*
* @param indexName
* @param id
* @return
*/
public boolean deleteById(String indexName, String id) {
DeleteRequest request = new DeleteRequest(indexName, id);
DeleteResponse response = null;
try {
response = client.delete(request, RequestOptions.DEFAULT);
if (response.status().getStatus() == HttpStatus.SC_CREATED
|| response.status().getStatus() == HttpStatus.SC_OK) {
LOGGER.info("delete success");
return true;
} else {
LOGGER.error("delete error : {}", response.toString());
return false;
}
} catch (IOException e) {
LOGGER.error("系统异常", e);
return false;
}
}
public <T> T search(SearchSourceBuilder sourceBuilder, CallbackSearch<T> callbackSearch) {
SearchRequest searchRequest = new SearchRequest().indices(INDEX_NAME).source(sourceBuilder);
SearchResponse response = null;
try {
response = client.search(searchRequest, RequestOptions.DEFAULT);
if (response.status().getStatus() == HttpStatus.SC_OK) {
// 提取数据
return callbackSearch.get(response);
} else {
LOGGER.error("index false, error : {}", response);
return null;
}
} catch (IOException e) {
LOGGER.error("系统异常", e);
return null;
}
}
/**
* 查询
*
* @param sourceBuilder
* @return
*/
public List<Map<String, Object>> searchResult(SearchSourceBuilder sourceBuilder) {
List<Map<String, Object>> searchResultList = this.search(sourceBuilder,
new CallbackSearch<List<Map<String, Object>>>() {
public List<Map<String, Object>> get(SearchResponse response) {
List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
SearchHit[] hitsArr = response.getHits().getHits();
for (int i = 0; i < hitsArr.length; i++) {
SearchHit hit = hitsArr[i];
Map<String, Object> resultMap = JSON.parseObject(hit.getSourceAsString(), HashMap.class);
resultList.add(resultMap);
}
return resultList;
}
});
return searchResultList;
}
public interface CallbackSearch<T> {
T get(SearchResponse response);
}
public static void main(String[] args) {
HighLevelRestClient restClient = new HighLevelRestClient();
// 1. 插入数据
String queryId = "2";
JSONObject jsonObj = new JSONObject();
jsonObj.put("id", "2");
jsonObj.put("question_id", "2020000010804111403");
jsonObj.put("uuid", "1596443685294289232");
jsonObj.put("question_type_id", "1");
jsonObj.put("question_content", "111车联网里面最常用的远控空调是如何运作的?需要先启动发动机吗?\",\r\n"
+ " \"answer_content\":\"远控空调需要先冷启动发动机,通过后台发送指令唤醒TCU,TCU唤醒后接收到指令则发出启动发动机信号,等待发动机启动成功后反馈结果到TCU,然后TCU通过XX信号反馈结果给到APP,在APP界面上反馈结果。");
boolean indexOK = restClient.indexById(restClient.INDEX_NAME, queryId, jsonObj.toJSONString());
// boolean indexOK = restClient.deleteById(restClient.INDEX_NAME, queryId);
LOGGER.info("index param={} result={}", queryId, indexOK);
if (indexOK) {
// 2. 数据检索
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
.query(QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("question_id", "2020000010804111403")))
// .sort("age", SortOrder.DESC)
.from(0).size(10);
List<Map<String, Object>> searchResultList = restClient.search(sourceBuilder,
new CallbackSearch<List<Map<String, Object>>>() {
public List<Map<String, Object>> get(SearchResponse response) {
List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
SearchHit[] hitsArr = response.getHits().getHits();
for (int i = 0; i < hitsArr.length; i++) {
SearchHit hit = hitsArr[i];
Map<String, Object> resultMap = JSON.parseObject(hit.getSourceAsString(),
HashMap.class);
resultList.add(resultMap);
}
return resultList;
}
});
LOGGER.info("search param={} result={}", sourceBuilder, JSON.toJSONString(searchResultList));
}
}
}
如上图代码中演示了新增或更新文档、删除、查询文档的调用方法,多个集群在
RestClient.builder(new HttpHost("172.26.239.235", 9200, "http"))这里多new几个放进去就会自动管理了,如
new HttpHost("172.26.239.235", 9200, "http"),new HttpHost("172.26.239.234", 9200, "http")
可以把这个工具类放入spring内管理,这样在项目中用的时候直接自动装配注入就行了。
补充:
本文演示的是单机版,通过简单的配置,elasticsearch可以很方便的实现多机器集群配置,这里不做过多介绍,有兴趣的同学可以参考这篇https://www.cnblogs.com/lowerma/p/12374114.html
网友评论