目录
Elasticsearch 是什么?
ES 是一个开源的高扩展的分布式全文搜索引擎,是面向文档型的NoSQL数据库,一条数据在这里就是一个文档。
Elasticsearch 环境搭建
软件下载地址:https://www.elastic.co/cn/downloads/past-releases/
-
多个不同的节点(es)要提供不同的端口号,将集群当成一个整体来使用。
-
一个 Elasticsearch 集群有一个唯一的名字标识,节点只能通过指定某个集群的名字,来加入这个集群。
-
注意:9300 端口为 Elasticsearch 集群间组件的通信端口,9200 端口为浏览器访问的 http协议 RESTful 端口。
-
Elasticsearch 是使用 java 开发的,且 7.8 版本的 ES 需要 JDK 版本 1.8 以上,默认安装包带有 jdk 环境,如果系统配置 JAVA_HOME,那么使用系统默认的 JDK,如果没有配置使用自带的 JDK,一般建议使用系统配置的 JDK。
-
注意要修改linux系统设置
-
检测集群健康状态
http://10.1.61.121:9200/_cat/nodes 10.1.61.121 13 84 2 0.25 0.19 0.22 dilmrt * node-1 10.1.61.122 36 99 1 0.13 0.13 0.15 dilmrt - node-2
参考:Elasticsearch7.x - 集群部署 - lihewei - 博客园 (cnblogs.com)
ES 相关操作(HTTP )
索引操作
es中的索引类似mysql中表的概念
1) 创建索引
向 ES 服务器发 PUT 请求 (注意:创建索引库的分片数默认 1 片,在 7.0.0 之前的 Elasticsearch 版本中,默认 5 片)
http://10.1.61.121:9200/shopping
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "shopping"
}
2)查看所有索引
在 Postman 中,向 ES 服务器发 GET 请求 :
- _cat 表示查看的意思
- indices 表示索引
http://10.1.61.121:9200/_cat/indices?v
3)查询单个索引
在 Postman 中,向 ES 服务器发 GET 请求 :
http://10.1.61.121:9200/shopping
4)删除索引
在 Postman 中,向 ES 服务器发 DELETE 请求 :
http://127.0.0.1:9200/shopping
文档操作
文档可以类比为关系型数据库中的表数据,添加的数据格式为 JSON 格式
1)创建文档
在 Postman 中,向 ES 服务器发 POST 请求 :(注意:类型设置为JSON)
http://10.1.61.121:9200/shopping/_doc
#或者指定id创建文档
http://10.1.61.121:9200/shopping/_doc/1
#请求体内容:
{
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":3999.00
}
返回结果
{
"_index"【索引】: "shopping",
"_type"【类型-文档】: "_doc",
"_id"【唯一标识】: "PTRCoYoBd1i1OTORc6Xn", #可以类比为 MySQL 中的主键,随机生成
"_version"【版本】: 1,
"result"【结果】: "created", #这里的 create 表示创建成功
"_shards"【分片】: {
"total"【分片 - 总数】: 2,
"successful"【分片 - 成功】: 1,
"failed"【分片 - 失败】: 0
},
"_seq_no": 0,
"_primary_term": 1
}
2)查看文档
在 Postman 中,向 ES 服务器发 GET 请求 :
http://10.1.61.121:9200/shopping/_doc/1
#返回结果
{
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"_version": 1,
"_seq_no": 1,
"_primary_term": 1,
"found": true, # true 表示查找到,false 表示未查找到
"_source": {
"title": "小米手机",
"category": "小米",
"images": "http://www.gulixueyuan.com/xm.jpg",
"price": 3999.00
}
}
3)修改文档
和新增文档一样,输入相同的 URL 地址请求,如果请求体变化,会将原有的数据内容覆盖(注:需要修改所有字段 )
在 Postman 中,向 ES 服务器发 POST 请求:
http://10.1.61.121:9200/shopping/_doc/1
{
"title":"华为手机",
"category":"华为",
"images":"http://www.gulixueyuan.com/hw.jpg",
"price":4999.00
}
4)修改字段
修改数据时,也可以只修改某一给条数据的局部信息,在 Postman 中,向 ES 服务器发 POST 请求
http://127.0.0.1:9200/shopping/_update/1
#请求体内容
{
"doc": {
"price":3000.00
}
}
5)删除文档
删除一个文档不会立即从磁盘上移除,它只是被标记成已删除(逻辑删除),根据ID去删除文档
在 Postman 中,向 ES 服务器发 DELETE 请求:
http://127.0.0.1:9200/shopping/_doc/1
6)条件删除
向 ES 服务器发 POST 请求:
http://127.0.0.1:9200/shopping/_delete_by_query
#请求体中输入要删除的条件
{
"query":{
"match":{
"price":4000.00
}
}
}
映射操作
创建数据库表需要设置字段名称,类型,长度,约束等;索引库也一样,需要知道这个类型下有哪些字段,每个字段有哪些约束信息,这就叫做映射(mapping)。
映射数据说明
- 字段名:任意填写,下面指定许多属性,例如:title、subtitle、images、price
- type:类型,Elasticsearch 中支持的数据类型非常丰富,说几个关键的:
- String 类型,又分两种:
- text:可分词
- keyword:不可分词,数据会作为完整字段进行匹配
- Numerical:数值类型,分两类
- 基本数据类型:long、integer、short、byte、double、float、half_float
- 浮点数的高精度类型:scaled_float
- Date:日期类型
- Array:数组类型
- Object:对象
- String 类型,又分两种:
- index:是否索引,默认为 true,也就是说你不进行任何配置,所有字段都会被索引。
- true:字段会被索引,则可以用来进行搜索
- false:字段不会被索引,不能用来搜索
- store:是否将数据进行独立存储,默认为 false:原始的文本会存储在_source 里面,默认情况下其他提取出来的字段都不是独立存储的,是从_source 里面提取出来的。当然你也可以独立的存储某个字段,只要设置"store": true 即可,获取独立存储的字段要比从_source 中解析快得多,但是也会占用更多的空间,所以要根据实际业务需求来设置。
- analyzer:分词器,这里的 ik_max_word 即使用 ik 分词器
索引映射关联
在 Postman 中,向 ES 服务器发 PUT 请求 :
http://10.1.61.121:9200/student1
#请求体
{
"settings": {},
"mappings": {
"properties": {
"name":{
"type": "text",
"index": true
},
"sex":{
"type": "text",
"index": false
},
"age":{
"type": "long",
"index": false
}
}
}
}
高级查询
Elasticsearch 提供了基于 JSON 提供完整的查询 DSL 来定义查询
1)查询所有文档
在 Postman 中,向 ES 服务器发 GET 请求 :
http://10.1.61.121:9200/student/_search
#请求体
{
"query": {
"match_all": {}
}
}
- "query":这里的 query 代表一个查询对象,里面可以有不同的查询属性
- "match_all":查询类型,例如:match_all(代表查询所有), match,term , range 等等
- {查询条件}:查询条件会根据类型的不同,写法也有差异
2)匹配查询
match 匹配类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是 or 的关系
在 Postman 中,向 ES 服务器发 GET 请求 :
http://127.0.0.1:9200/student/_search
#请求体
{
"query": {
"match": {
"name":"zhangsan"
}
}
}
3)字段匹配查询
multi_match 与 match 类似,不同的是它可以在多个字段中查询。
在 Postman 中,向 ES 服务器发 GET 请求 :
http://127.0.0.1:9200/student/_search
#请求体
{
"query": {
"multi_match": {
"query": "zhangsan",
"fields": ["name","nickname"]
}
}
}
4)关键字精确查询
term 查询,精确的关键词匹配查询,不对查询条件进行分词。
在 Postman 中,向 ES 服务器发 GET 请求 :
http://127.0.0.1:9200/student/_search
#请求体
{
"query": {
"term": {
"name": {
"value": "zhangsan"
}
}
}
}
#多关键字精确查询
{
"query": {
"terms": {
"name": ["zhangsan","lisi"]
}
}
}
5)查询指定字段(过滤)
默认情况下,Elasticsearch 在搜索的结果中,会把文档中保存在_source 的所有字段都返回。如果我们只想获取其中的部分字段,我们可以添加_source 的过滤
在 Postman 中,向 ES 服务器发 GET 请求 :
http://127.0.0.1:9200/student/_search
#请求体
{
"_source": ["name","nickname"], #指定想要保留的字段
"query": {
"terms": {
"nickname": ["zhangsan"]
}
}
}
过滤字段
- includes:来指定想要显示的字段
- excludes:来指定不想要显示的字段
{
"_source": {
"includes": ["name","nickname"] #保留的字段
},
"query": {
"terms": {
"nickname": ["zhangsan"]
}
}
}
# 或者
{
"_source": {
"excludes": ["name","nickname"] #排除的字段
},
"query": {
"terms": {
"nickname": ["zhangsan"]
}
}
}
6)组合查询
bool
把各种其它查询通过
must
(必须 )must_not
(必须不)should
(应该)的方
式进行组合
在 Postman 中,向 ES 服务器发 GET 请求 :
http://127.0.0.1:9200/student/_search
# 请求体
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "zhangsan"
}
}
],
"must_not": [
{
"match": {
"age": "40"
}
}
],
"should": [
{
"match": {
"sex": "男"
}
}
]
}
}
}
7)范围查询
range 查询找出那些落在指定区间内的数字或者时间。range 查询允许以下字符
操作符 | 说明 |
---|---|
gt | 大于> |
gte | 大于等于>= |
lt | 小于< |
lte | 小于等于<= |
在 Postman 中,向 ES 服务器发 GET 请求 :
http://127.0.0.1:9200/student/_search
#请求体
{
"query": {
"range": {
"age": {
"gte": 30,
"lte": 35
}
}
}
}
8)模糊查询
返回包含与搜索字词相似的字词的文档。为了找到相似的词,模糊查询会在指定的编辑距离内创建搜索词的所有可能变化或者扩展的集合,查询然后返回每个扩展的完全匹配。
通过 fuzziness 修改编辑距离。一般使用默认值 AUTO,根据术语的长度生成编辑距离。("fuzziness": "x" 容许几个编辑错误)
#插入一条数据“I like blue sky”
PUT fuzzyindex/_doc/1
{
"content": "I like blue sky"
}
查询条件中输入"ski",查不到任何结果
#查询条件中输入"ski",查不到任何结果
GET fuzzyindex/_search
{
"query": {
"match": {
"content": "ski"
}
}
}
#结果
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}
查询时,添加参数:
GET fuzzyindex/_search
{
"query": {
"match": {
"content": {
"query": "ski",
"fuzziness": "1"
}
}
}
}
#查询结果
{
"took" : 18,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.19178805,
"hits" : [
{
"_index" : "fuzzyindex",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.19178805,
"_source" : {
"content" : "I like blue sky"
}
}
]
}
}
9)字段排序
sort 可以让我们按照不同的字段进行排序,并且通过 order 指定排序的方式。desc 降序,asc升序。
在 Postman 中,向 ES 服务器发 GET 请求 :
http://127.0.0.1:9200/student/_search
#请求体
{
"query": {
"match": {
"name":"zhangsan"
}
},
"sort": [{
"age": {
"order":"desc"
}
}]
}
假定我们想要结合使用 age 和 _score 进行查询,并且匹配的结果首先按照年龄排序,然后按照相关性得分排序,例如:
http://127.0.0.1:9200/student/_search
#请求体
{
"query": {
"match_all": {}
},
"sort": [
{
"age": {
"order": "desc"
}
},
{
"_score":{
"order": "desc"
}
}
]
}
10)高亮查询
在使用 match 查询的同时,加上一个 highlight 属性:
- pre_tags:前置标签
- post_tags:后置标签
- fields:需要高亮的字段
- title:这里声明 title 字段需要高亮,后面可以为这个字段设置特有配置,也可以空
在 Postman 中,向 ES 服务器发 GET 请求 :
http://127.0.0.1:9200/student/_search
#请求体
{
"query": {
"match": {
"name": "zhangsan"
}
},
"highlight": {
"pre_tags": "<font color='red'>",
"post_tags": "</font>",
"fields": {
"name": {}
}
}
}
11)分页查询
- from:当前页的起始索引,默认从 0 开始。 from = (pageNum - 1) * size
- size:每页显示多少条
在 Postman 中,向 ES 服务器发 GET 请求 :
http://127.0.0.1:9200/student/_search
#请求体
{
"query": {
"match_all": {}
},
"sort": [
{
"age": {
"order": "desc"
}
}
],
"from": 0,
"size": 2
}
12)聚合查询
聚合允许使用者对 es 文档进行统计分析,类似与关系型数据库中的 group by,当然还有很多其他的聚合,例如取最大值、平均值等等。
- 对某个字段取最大值 max
- 对某个字段取最小值 min
- 对某个字段求和 sum
- 对某个字段取平均值 avg
- 对某个字段的值进行去重之后再取总数
- State 聚合(对某个字段一次性返回 count,max,min,avg 和 sum 五个指标)
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/student/_search
http://10.1.61.121:9200/student/_search
#请求体
#对某个字段取最大值 max
{
"aggs":{
"max_age":{
"max":{"field":"age"}
}
},
"size":0
}
#对某个字段取最小值 min
{
"aggs":{
"min_age111":{#可自定义
"min":{"field":"age"}
}
},
"size":0
}
#对某个字段求和 sum
{
"aggs":{
"sum_age":{
"sum":{"field":"age"}
}
},
"size":0
}
#对某个字段取平均值 avg
{
"aggs":{
"avg_age":{
"avg":{"field":"age"}
}
},
"size":0
}
#对某个字段的值进行去重之后再取总数
{
"aggs":{
"distinct_age":{
"cardinality":{"field":"age"}
}
},
"size":0
}
#对某个字段一次性返回 count,max,min,avg 和 sum 五个指标
{
"aggs":{
"stats_age":{
"stats":{"field":"age"}
}
},
"size":0
}
13)桶聚合查询
- terms 聚合,分组统计,相当于 sql 中的 group by 语句
在 Postman 中,向 ES 服务器发 GET 请求 :
http://127.0.0.1:9200/student/_search
#请求体(统计分组后的数量)
#按年龄分组,然后统计每个年龄人数 count(*) ,age xxx group by age
{
"aggs": {
"by_age": {
"terms": {
# age 为数值,可以直接分组
"field": "age"
}
}
}
}
#ES没有对文本字段聚合,排序等操作优化;如果对文本字段进行分组,推荐使用 关键字字段
{
"aggs": {
"by_age": {
"terms": {
"field": "city.keyword"
}
}
}
}
ES Java API 相关操作
Elasticsearch 软件是由 Java 语言开发的,所以也可以通过 Java API 的方式对 Elasticsearch服务进行访问
1)导入POM依赖
<dependencies>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.8.0</version>
</dependency>
<!-- elasticsearch 的客户端 -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.8.0</version>
</dependency>
<!-- elasticsearch 依赖 2.x 的 log4j -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9</version>
</dependency>
<!-- junit 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
2)创建REST客户端对象
// 创建客户端对象
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
...
// 关闭客户端连接
client.close();
注意:9200 端口为 Elasticsearch 的 Web 通信端口
3)索引操作
创建索引
// 创建索引 - 请求对象
CreateIndexRequest request = new CreateIndexRequest("user");
// 发送请求,获取响应
CreateIndexResponse response = client.indices().create(request,
RequestOptions.DEFAULT);
boolean acknowledged = response.isAcknowledged();
// 响应状态
System.out.println("操作状态 = " + acknowledged);
查看索引
// 查询索引 - 请求对象
GetIndexRequest request = new GetIndexRequest("user");
// 发送请求,获取响应
GetIndexResponse response = client.indices().get(request,
RequestOptions.DEFAULT);
System.out.println("aliases:"+response.getAliases());
System.out.println("mappings:"+response.getMappings());
System.out.println("settings:"+response.getSettings());
删除索引
// 删除索引 - 请求对象
DeleteIndexRequest request = new DeleteIndexRequest("user");
// 发送请求,获取响应
AcknowledgedResponse response = client.indices().delete(request,
RequestOptions.DEFAULT);
// 操作结果
System.out.println("操作结果 : " + response.isAcknowledged());
4)文档操作
准备实体
@Data
public class User {
private String name;
private Integer age;
private String sex;
}
新增文档
// 新增文档 - 请求对象
IndexRequest request = new IndexRequest();
// 设置索引及唯一性标识
request.index("user").id("1001");
// 创建数据对象
User user = new User();
user.setName("zhangsan");
user.setAge(30);
user.setSex("男");
ObjectMapper objectMapper = new ObjectMapper();
String productJson = objectMapper.writeValueAsString(user);
// 添加文档数据,数据格式为 JSON 格式
request.source(productJson,XContentType.JSON);
// 客户端发送请求,获取响应对象
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
////3.打印结果信息
System.out.println("_index:" + response.getIndex());
System.out.println("_id:" + response.getId());
System.out.println("_result:" + response.getResult());
修改文档
// 修改文档 - 请求对象
UpdateRequest request = new UpdateRequest();
// 配置修改参数
request.index("user").id("1001");
// 设置请求体,对数据进行修改
request.doc(XContentType.JSON, "sex", "女");
// 客户端发送请求,获取响应对象
UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
System.out.println("_index:" + response.getIndex());
System.out.println("_id:" + response.getId());
System.out.println("_result:" + response.getResult());
查询文档
//1.创建请求对象
GetRequest request = new GetRequest().index("user").id("1001");
//2.客户端发送请求,获取响应对象
GetResponse response = client.get(request, RequestOptions.DEFAULT);
////3.打印结果信息
System.out.println("_index:" + response.getIndex());
System.out.println("_type:" + response.getType());
System.out.println("_id:" + response.getId());
System.out.println("source:" + response.getSourceAsString());
删除文档
//创建请求对象
DeleteRequest request = new DeleteRequest().index("user").id("1");
//客户端发送请求,获取响应对象
DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
//打印信息
System.out.println(response.toString());
批量新增
//创建批量新增请求对象
BulkRequest request = new BulkRequest();
request.add(new
IndexRequest().index("user").id("1001").source(XContentType.JSON, "name",
"zhangsan"));
request.add(new IndexRequest().index("user").id("1002").source(XContentType.JSON, "name", "lisi"));
request.add(new IndexRequest().index("user").id("1003").source(XContentType.JSON, "name", "wangwu"));
//客户端发送请求,获取响应对象
BulkResponse responses = client.bulk(request, RequestOptions.DEFAULT);
//打印结果信息
System.out.println("took:" + responses.getTook());
System.out.println("items:" + responses.getItems());
批量删除
//创建批量删除请求对象
BulkRequest request = new BulkRequest();
request.add(new DeleteRequest().index("user").id("1001"));
request.add(new DeleteRequest().index("user").id("1002"));
request.add(new DeleteRequest().index("user").id("1003"));
//客户端发送请求,获取响应对象
BulkResponse responses = client.bulk(request, RequestOptions.DEFAULT);
//打印结果信息
System.out.println("took:" + responses.getTook());
System.out.println("items:" + responses.getItems());
5)高级查询
查询索引的所有数据
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("student");
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 查询所有数据
sourceBuilder.query(QueryBuilders.matchAllQuery());
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
//输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
}
System.out.println("<<========");
条件查询(term查询)
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("student");
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termQuery("age", "30"));
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
//输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
}
System.out.println("<<========");
分页查询
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("student");
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchAllQuery());
// 分页查询
// 当前页其实索引(第一条数据的顺序号),from
sourceBuilder.from(0);
// 每页显示多少条 size
sourceBuilder.size(2);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
//输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
}
System.out.println("<<========");
数据排序
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchAllQuery());
// 排序
sourceBuilder.sort("age", SortOrder.ASC);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
//输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
}
System.out.println("<<========");
过滤字段
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("student");
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchAllQuery());
//查询字段过滤
String[] excludes = {};
String[] includes = {"name", "age"};
sourceBuilder.fetchSource(includes, excludes);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
//输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
}
System.out.println("<<========");
Bool查询
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("student");
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
// 必须包含
boolQueryBuilder.must(QueryBuilders.matchQuery("age", "30"));
// 一定不含
boolQueryBuilder.mustNot(QueryBuilders.matchQuery("name", "zhangsan"));
// 可能包含
boolQueryBuilder.should(QueryBuilders.matchQuery("sex", "男"));
sourceBuilder.query(boolQueryBuilder);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
//输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
}
System.out.println("<<========");
范围查询
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("student");
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
// 大于等于
rangeQuery.gte("30");
// 小于等于
rangeQuery.lte("40");
sourceBuilder.query(rangeQuery);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
//输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
}
System.out.println("<<========");
模糊查询
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("student");
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.fuzzyQuery("name","zhangsan").fuzziness(Fu
zziness.ONE));
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
//输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
}
System.out.println("<<========");
高亮查询
// 高亮查询
SearchRequest request = new SearchRequest().indices("student");
//2.创建查询请求体构建器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//构建查询方式:高亮查询
TermsQueryBuilder termsQueryBuilder =
QueryBuilders.termsQuery("name","zhangsan");
//设置查询方式
sourceBuilder.query(termsQueryBuilder);
//构建高亮字段
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("<font color='red'>");//设置标签前缀
highlightBuilder.postTags("</font>");//设置标签后缀
highlightBuilder.field("name");//设置高亮字段
//设置高亮构建对象
sourceBuilder.highlighter(highlightBuilder);
//设置请求体
request.source(sourceBuilder);
//3.客户端发送请求,获取响应对象
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.打印响应结果
SearchHits hits = response.getHits();
System.out.println("took::"+response.getTook());
System.out.println("time_out::"+response.isTimedOut());
System.out.println("total::"+hits.getTotalHits());
System.out.println("max_score::"+hits.getMaxScore());
System.out.println("hits::::>>");
for (SearchHit hit : hits) {
String sourceAsString = hit.getSourceAsString();
System.out.println(sourceAsString);
//打印高亮结果
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
System.out.println(highlightFields);
}
System.out.println("<<::::");
聚合查询
SearchRequest request = new SearchRequest().indices("student");
//最大年龄
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.aggregation(AggregationBuilders.max("maxAge").field("age"));
//分组统计
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.aggregation(AggregationBuilders.terms("age_groupby").field("age"));
...
//设置请求体
request.source(sourceBuilder);
//3.客户端发送请求,获取响应对象
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.打印响应结果
SearchHits hits = response.getHits();
System.out.println(response);
ES 核心概念
倒排索引
-
正排索引:(正向索引):
例如编号设置索引,通过索引可以快速关联到存储信息
id tontent -------------------------------- 1001 my name is zhangsan 1002 my name is lisi
-
倒排索引:
关键字与文章ID进行关联(通过关键字查询主键ID,然后在关联文章内容)
keyword id -------------------------------- name 1001,1002 zhangsan 1001