文章目录
- 控制台RESTFULL操作
- REST风格说明
- 基于REST命令说明:
- es支持的数据类型
- 核心数据类型
- ik分词器使用
- ik_smart最少切分
- ik_max_word最细粒度
- 索引操作
- 索引库创建
- 创建文档方式
- 指定索引类型(以后这种方式会被弃用)
- 不指定索引类型利用默认的_doc类型
- 更新文档
- 方式一:
- 方式二:推荐使用这种方式修改更加高效
- 删除操作
- 查询操作
- 按照id查询
- 搜索
- 简单查询
- 匹配
- 结果过滤:
- 排序
- 分页查询
- 匹配多个条件
- 精确查询
- 高亮查询
- 默认高亮标签
- 自定义高亮标签
- 布尔查询
- match
- should
- must_not
- filter
- java API使用
- 官方文档
- RestClient和TransportClient区别?
- Java Low Level REST Client 和 Java High Level REST Client区别?
- API使用
- 获取连接
- 创建索引库
- 删除索引库/判断索引库是否存在
- 添加文档
- 更新文档
- 获取新闻文档
- 批量插入文档
- 搜索
- springBoot整合elasticSearch 7
- 新建项目
- 导入依赖
- 创建类
- 配置类
- 实体类
- 测试类
控制台RESTFULL操作
使用工具Cerebro v0.8.3
REST风格说明
一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件。主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简介,更有层次,更易于实现缓存等机制
基于REST命令说明:
method | url地址 | 描述 |
---|---|---|
PUT | localhost:9200/索引名称/类型名称/文档id | 创建文档(指定文档id) |
POST | localhost:9200/索引名称/类型名称 | 创建文档(随机文档id) |
POST | localhost:9200/索引名称/类型名称/文档id/_update | 更新文档 |
DELETE | localhost:9200/索引名称/类型名称/文档id | 删除文档 |
GET | localhost:9200/索引名称/类型名称/文档id | 通过docId查询文档 |
POST | localhost:9200/索引名称/类型名称/_search | 查询所有数据 |
es支持的数据类型
核心数据类型
(1)字符串类型: text, keyword
(2)数字类型:long, integer, short, byte, double, float, half_float, scaled_float
(3)日期:date
(4)日期 纳秒:date_nanos
(5)布尔型:boolean
(6)Binary:binary
(7)Range: integer_range, float_range, long_range, double_range, date_range
其他类型!
ik分词器使用
ik_smart最少切分
请求服务名:_analyze
请求方式:GET
请求体:
{"analyzer":"ik_smart","text":" 和尚和未结婚的和尚结婚了"
}
返回:
{"tokens": [{"token": "和尚","start_offset": 1,"end_offset": 3,"type": "CN_WORD","position": 0},{"token": "和","start_offset": 3,"end_offset": 4,"type": "CN_CHAR","position": 1},{"token": "未","start_offset": 4,"end_offset": 5,"type": "CN_CHAR","position": 2},{"token": "结婚","start_offset": 5,"end_offset": 7,"type": "CN_WORD","position": 3},{"token": "的","start_offset": 7,"end_offset": 8,"type": "CN_CHAR","position": 4},{"token": "和尚","start_offset": 8,"end_offset": 10,"type": "CN_WORD","position": 5},{"token": "结婚","start_offset": 10,"end_offset": 12,"type": "CN_WORD","position": 6},{"token": "了","start_offset": 12,"end_offset": 13,"type": "CN_CHAR","position": 7}]
}
操作截图
ik_max_word最细粒度
请求服务名:_analyze
请求方式:GET
请求体:
{"analyzer":"ik_max_word","text":" 和尚和未结婚的和尚结婚了"
}
返回:
{"tokens": [{"token": "和尚","start_offset": 1,"end_offset": 3,"type": "CN_WORD","position": 0},{"token": "和","start_offset": 3,"end_offset": 4,"type": "CN_CHAR","position": 1},{"token": "未结","start_offset": 4,"end_offset": 6,"type": "CN_WORD","position": 2},{"token": "结婚","start_offset": 5,"end_offset": 7,"type": "CN_WORD","position": 3},{"token": "的","start_offset": 7,"end_offset": 8,"type": "CN_CHAR","position": 4},{"token": "和尚","start_offset": 8,"end_offset": 10,"type": "CN_WORD","position": 5},{"token": "结婚","start_offset": 10,"end_offset": 12,"type": "CN_WORD","position": 6},{"token": "了","start_offset": 12,"end_offset": 13,"type": "CN_CHAR","position": 7}]
}
操作截图:
索引操作
索引库创建
mappings好比mysql数据库中创建表结构,es通过mappings来创建索引规则
PUT 索引库名称
例如:PUT test2
{"mappings":{"properties":{"name":{"type":"text"},"age":{"type":"long"},"birthday":{"type":"date"}}}}
返回:
{"acknowledged": true,"shards_acknowledged": true,"index": "test2"
}
查看索引库是否创建成功:GET test2
{"test2": {"aliases": {},"mappings": {"properties": {"age": {"type": "long"},"birthday": {"type": "date"},"name": {"type": "text"}}},"settings": {"index": {"creation_date": "1605249683965","number_of_shards": "1","number_of_replicas": "1","uuid": "TuEFwhYdRHC01ZRvkcZiGQ","version": {"created": "7070099"},"provided_name": "test2"}}}
}
创建文档方式
如果索引库没有配置mapping,es会给我们默认配置字段类型
method | url地址 | 描述 |
---|---|---|
PUT | localhost:9200/索引名称/类型名称/文档id | 创建文档(指定文档id) |
指定索引类型(以后这种方式会被弃用)
不指定索引类型利用默认的_doc类型
PUT test3/_doc/1
{"name":"魏杰","age":25,"birth":"1995-10-01"
}
返回:
{"_index": "test3","_type": "_doc","_id": "1","_version": 1,"result": "created","_shards": {"total": 2,"successful": 1,"failed": 0},"_seq_no": 0,"_primary_term": 1
}
查看索引库会自动配置默认字段类型
请求:GET test2
返回:
{"test2": {"aliases": {},"mappings": {"properties": {"age": {"type": "long"},"birth": {"type": "date"},"birthday": {"type": "date"},"name": {"type": "text"}}},"settings": {"index": {"creation_date": "1605249683965","number_of_shards": "1","number_of_replicas": "1","uuid": "TuEFwhYdRHC01ZRvkcZiGQ","version": {"created": "7070099"},"provided_name": "test2"}}}
}
更新文档
修改 提交还是使用PUT即可!然后覆盖!最新办法使用update!
方式一:
PUT test3/_doc/1
{"name":"魏杰2","age":21,"birth":"1995-11-01"}
返回:
{"_index": "test3","_type": "_doc","_id": "1","_version": 2,"result": "updated","_shards": {"total": 2,"successful": 1,"failed": 0},"_seq_no": 1,"_primary_term": 1
}
_version可以看出版本号发生了更新,result是updated表示发生了更新
这种更新方式的缺点是每次都需要传所有数据,而不能指定某个域去更新数据
方式二:推荐使用这种方式修改更加高效
POST test3/_doc/1/_update
{"doc":{"name":"盲僧"}
}
删除操作
通过DELETE命令实现删除,根据你的请求来判断是删除索引还是删除文档记录!
使用RESTFUL风格是es推荐大家使用的
查询操作
按照id查询
GET user/_doc/1
搜索
简单查询
GET user/_doc/_search?q=name:c
匹配
GET user/_doc/_search
{"query":{"match":{"name":"c"}}
}
结果过滤:
_source:字段用来过滤搜索出的结果
GET user/_doc/_search
{"query":{"match":{"name":"c"}},"_source":["name","age"]
}
排序
利用sort构建排序,asc:升序、desc:降序 可以结合mysql来记忆
GET user/_doc/_search
{"query":{"match":{"name":"c"}},"sort":[{"age":{"order":"desc"}}]
}
分页查询
添加from、size参数即可
GET user/_doc/_search
{"query":{"match":{"name":"c"}},"sort":[{"age":{"order":"desc"}}],"from":0,"size":1
}
匹配多个条件
利用空格隔开
user/_doc/_search
{"query":{"match":{"name":"c java"}}
}
精确查询
term查询是直接通过倒排索引指定的词条进行精确查找的
关于分词:
- term:直接从倒排中精准查询
- match:会使用分词器解析,先分析文档,然后再查询
两个类型 text 和 keyword
- keyword类型不会被分词器分词,keyword类型只能被精准查询
- text类型会被分词器分词
利用term + bool可以精确查询多个值
高亮查询
默认高亮标签
highlight->fields->name:表示对name字段值输出高亮显示
{"query":{"bool":{"should":[{"match":{"name":"杰"}}]}},"highlight":{"fields":{"name":{}}}
}
自定义高亮标签
{"query":{"bool":{"should":[{"match":{"name":"杰"}}]}},"highlight":{"pre_tags":"<p class='key' style='color:red'>","post_tags":"</p>","fields":{"name":{}}}
}
布尔查询
加上bool参数
match
对应mysql中的and,两个条件必须都满足
GET user/_doc/_search
{"query":{"bool":{"must":[{"match":{"name":"c"}},{"match":{"age":25}}]}}
}
should
对应mysql中的or,两个满足一个即可
GET user/_doc/_search
{"query":{"bool":{"should":[{"match":{"name":"c"}},{"match":{"age":28}}]}}
}
must_not
对应mysql中的not
GET user/_doc/_search
{"query":{"bool":{"must_not":[{"match":{"name":"c"}}]}}
}
filter
利用filter对数据过滤,区间查询
GET user/_doc/_search
{"query":{"bool":{"must":[{"match":{"name":"c"}}],"filter":{"range":{"age":{"lt":25}}}}}
}
- gt:大于
- gte:大于等于
- lt:小于
- lte:小于等于!
java API使用
官方文档
RestClient和TransportClient区别?
TransportClient基于TCP协议、Rest Client 基于Http协议;
详细说明:https://blog.csdn.net/huoqilinheiqiji/article/details/89713412
Java Low Level REST Client 和 Java High Level REST Client区别?
低级别客户端:允许通过http请求与es集群进行通信,API本身不负责数据的编码解码,由用于去编码解码,它与所有的es版本兼容。
高级别客户端:es官方高级客户端,基于低级客户端,它定义的API,已经对请求与响应数据包进行编解码
API使用
获取连接
@Beanpublic RestHighLevelClient restHighLevelClient(){RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1", 9200, "http")));return client;}
创建索引库
/*** 创建索引库 PUT test_index*/@Testvoid createIndex() throws IOException {//1.创建索引请求CreateIndexRequest request = new CreateIndexRequest(INDEX_NAME);//2.执行创建请求,获取响应 indices:index复数CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);System.out.println(createIndexResponse);}
删除索引库/判断索引库是否存在
/*** 获取索引库 GET test_index*/@Testvoid testExistIndex() throws IOException {GetIndexRequest request = new GetIndexRequest(INDEX_NAME);
// new DeleteIndexRequest() 删除索引库boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);Assertions.assertEquals(true, exists);}
添加文档
/*** 添加文档* PUT test_index/_doc/1* {* "name":"小明",* "age":"25";* }*/@Testvoid createDocument() throws IOException {//创建对象User user = new User("小明", 25);//创建请求IndexRequest indexRequest = new IndexRequest(INDEX_NAME);// PUT indexName/_doc/1indexRequest.id("1").timeout(TimeValue.timeValueSeconds(1));//将我们的数据放入请求 jsonindexRequest.source(JSON.toJSONString(user), XContentType.JSON);//客户端发送请求IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);//对应我们命令返回的状态:created/updatedSystem.out.println(indexResponse.status());System.out.println(indexRequest.toString());}
更新文档
/*** 更新文档方式一:* PUT test_index/_doc/1* {* "name":"小红",* "age":"25"* }* 更新文档方式二:* PUT test_index/_doc/1/_update* {* "doc"{* "name":"小红"* }* }*/@Testvoid updateDocument() throws IOException {UpdateRequest updateRequest = new UpdateRequest(INDEX_NAME, "1");//方式一
// HashMap<String, Object> updateFieldsMap = new HashMap<>();
// updateFieldsMap.put("name", "小红");
// updateRequest.doc(updateFieldsMap);//方式二User user = new User("疾风剑豪",25);updateRequest.doc(JSON.toJSONString(user), XContentType.JSON);client.update(updateRequest, RequestOptions.DEFAULT);queryDocument();}
获取新闻文档
/*** 获取文档* GET test_index/_doc/1*/@Testvoid queryDocument() throws IOException{GetRequest request = new GetRequest(INDEX_NAME);request.id("1");//不返回 _source结果,效率更高
// request.fetchSourceContext(new FetchSourceContext(false));//设置某个字段单独放在GetResponse对象中
// request.storedFields("_none_");//判断文档是否存在
// boolean exists = client.exists(request, RequestOptions.DEFAULT);GetResponse response = client.get(request, RequestOptions.DEFAULT);String cnt = response.getSourceAsString();System.out.println(cnt);//返回全部内容和命令一样/*** {* "_index": "test_index",* "_type": "_doc",* "_id": "1",* "_version": 1,* "_seq_no": 0,* "_primary_term": 1,* "found": true,* "_source": {* "age": 25,* "name": "小明"* }* }*/System.out.println(response);}
批量插入文档
/*** 批量插入数据*/@Testvoid bulkRequest() throws IOException {BulkRequest bulkRequest = new BulkRequest();bulkRequest.timeout("10s");for (int i = 2; i < 10; i++){User user = new User("name-" + i, i);IndexRequest indexRequest = new IndexRequest(INDEX_NAME);//不用id会生成一个随机的idindexRequest.id(i + "").source(JSON.toJSONString(user), XContentType.JSON);bulkRequest.add(indexRequest);}client.bulk(bulkRequest, RequestOptions.DEFAULT);}
搜索
/*** 查询* GET test_index/_doc/_search?* {* "query":{* "match":"name:剑豪"* }* }*/@Testvoid search() throws IOException {SearchRequest searchRequest = new SearchRequest(INDEX_NAME);//构建搜索条件,我们可以使用QueryBuilders工具来实现SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();/**"highlight":{"pre_tags":"<p class='key' style='color:red'>","post_tags":"</p>","fields":{"name":{}}}*/HighlightBuilder highlightBuilder = new HighlightBuilder();highlightBuilder.field("name");//关闭多个高亮显示,只高亮首次匹配即可highlightBuilder.requireFieldMatch(false);highlightBuilder.preTags("<span style='color:red'>");highlightBuilder.postTags("</span>");sourceBuilder.highlighter(highlightBuilder);
// QueryBuilder queryBuilder = new QueryBuilder();MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "name");sourceBuilder.query(queryBuilder);//设置查询超时时间sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
// sourceBuilder.from(0);
// sourceBuilder.size(20);searchRequest.source(sourceBuilder);SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);SearchHit[] hits = searchResponse.getHits().getHits();for (SearchHit hit : hits){//解析高亮的字段Map<String, HighlightField> highlightFields = hit.getHighlightFields();HighlightField name = highlightFields.get("name");Map<String, Object> sourceAsMap = hit.getSourceAsMap();//如果当前高亮字段不为null,将原来的字段换成我们高亮的字段即可if (name != null){//获取高亮的片段Text[] fragments = name.fragments();//替换StringBuilder stringBuilder = new StringBuilder();for (Text text : fragments){stringBuilder.append(text);}sourceAsMap.put("name", stringBuilder.toString());}System.out.println(sourceAsMap.toString());}}
springBoot整合elasticSearch 7
新建项目
导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.0</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>csdn.dreamzuora</groupId><artifactId>es-api</artifactId><version>0.0.1-SNAPSHOT</version><name>es-api</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version><!--自定义es版本依赖,保证和自己版本一致--><elasticsearch.version>7.6.1</elasticsearch.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.75</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
注意:如果当前springBoot版本默认导入的spring-boot-starter-data-elasticsearch使用的是老版本需要<elasticsearch.version>7.6.1</elasticsearch.version>中去指定版本
创建类
配置类
package csdn.dreamzuora.config;import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** Title: es客户端配置信息* Description:** @version 1.0* @author: weijie* @date: 2020/11/19 18:15*/
@Configuration
public class EsConfig {@Beanpublic RestHighLevelClient restHighLevelClient(){RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1", 9200, "http")));return client;}}
实体类
package csdn.dreamzuora.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** Title:* Description:** @version 1.0* @author: weijie* @date: 2020/11/19 18:40*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private String name;private int age;
}
测试类
package csdn.dreamzuora;import com.alibaba.fastjson.JSON;
import csdn.dreamzuora.pojo.User;
import org.apache.lucene.util.QueryBuilder;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
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.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;@SpringBootTest
class EsApiApplicationTests {@Autowired@Qualifier("restHighLevelClient")private RestHighLevelClient client;private String INDEX_NAME = "test_index";/*** 创建索引库 PUT test_index*/@Testvoid createIndex() throws IOException {//1.创建索引请求CreateIndexRequest request = new CreateIndexRequest(INDEX_NAME);//2.执行创建请求,获取响应 indices:index复数CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);System.out.println(createIndexResponse);}/*** 获取索引库 GET test_index*/@Testvoid testExistIndex() throws IOException {GetIndexRequest request = new GetIndexRequest(INDEX_NAME);
// new DeleteIndexRequest() 删除索引库boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);Assertions.assertEquals(true, exists);}/*** 添加文档* PUT test_index/_doc/1* {* "name":"小明",* "age":"25";* }*/@Testvoid createDocument() throws IOException {//创建对象User user = new User("小明", 25);//创建请求IndexRequest indexRequest = new IndexRequest(INDEX_NAME);// PUT indexName/_doc/1indexRequest.id("1").timeout(TimeValue.timeValueSeconds(1));//将我们的数据放入请求 jsonindexRequest.source(JSON.toJSONString(user), XContentType.JSON);//客户端发送请求IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);//对应我们命令返回的状态:created/updatedSystem.out.println(indexResponse.status());System.out.println(indexRequest.toString());}/*** 更新文档方式一:* PUT test_index/_doc/1* {* "name":"小红",* "age":"25"* }* 更新文档方式二:* PUT test_index/_doc/1/_update* {* "doc"{* "name":"小红"* }* }*/@Testvoid updateDocument() throws IOException {UpdateRequest updateRequest = new UpdateRequest(INDEX_NAME, "1");//方式一
// HashMap<String, Object> updateFieldsMap = new HashMap<>();
// updateFieldsMap.put("name", "小红");
// updateRequest.doc(updateFieldsMap);//方式二User user = new User("疾风剑豪",25);updateRequest.doc(JSON.toJSONString(user), XContentType.JSON);client.update(updateRequest, RequestOptions.DEFAULT);queryDocument();}/*** 获取文档* GET test_index/_doc/1*/@Testvoid queryDocument() throws IOException{GetRequest request = new GetRequest(INDEX_NAME);request.id("1");//不返回 _source结果,效率更高
// request.fetchSourceContext(new FetchSourceContext(false));//设置某个字段单独放在GetResponse对象中
// request.storedFields("_none_");//判断文档是否存在
// boolean exists = client.exists(request, RequestOptions.DEFAULT);GetResponse response = client.get(request, RequestOptions.DEFAULT);String cnt = response.getSourceAsString();System.out.println(cnt);//返回全部内容和命令一样/*** {* "_index": "test_index",* "_type": "_doc",* "_id": "1",* "_version": 1,* "_seq_no": 0,* "_primary_term": 1,* "found": true,* "_source": {* "age": 25,* "name": "小明"* }* }*/System.out.println(response);}/*** 批量插入数据*/@Testvoid bulkRequest() throws IOException {BulkRequest bulkRequest = new BulkRequest();bulkRequest.timeout("10s");for (int i = 2; i < 10; i++){User user = new User("name-" + i, i);IndexRequest indexRequest = new IndexRequest(INDEX_NAME);//不用id会生成一个随机的idindexRequest.id(i + "").source(JSON.toJSONString(user), XContentType.JSON);bulkRequest.add(indexRequest);}client.bulk(bulkRequest, RequestOptions.DEFAULT);}/*** 查询* GET test_index/_doc/_search?* {* "query":{* "match":"name:剑豪"* }* }*/@Testvoid search() throws IOException {SearchRequest searchRequest = new SearchRequest(INDEX_NAME);//构建搜索条件,我们可以使用QueryBuilders工具来实现SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();/**"highlight":{"pre_tags":"<p class='key' style='color:red'>","post_tags":"</p>","fields":{"name":{}}}*/HighlightBuilder highlightBuilder = new HighlightBuilder();highlightBuilder.field("name");//关闭多个高亮显示,只高亮首次匹配即可highlightBuilder.requireFieldMatch(false);highlightBuilder.preTags("<span style='color:red'>");highlightBuilder.postTags("</span>");sourceBuilder.highlighter(highlightBuilder);
// QueryBuilder queryBuilder = new QueryBuilder();MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "name");sourceBuilder.query(queryBuilder);//设置查询超时时间sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
// sourceBuilder.from(0);
// sourceBuilder.size(20);searchRequest.source(sourceBuilder);SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);SearchHit[] hits = searchResponse.getHits().getHits();for (SearchHit hit : hits){//解析高亮的字段Map<String, HighlightField> highlightFields = hit.getHighlightFields();HighlightField name = highlightFields.get("name");Map<String, Object> sourceAsMap = hit.getSourceAsMap();//如果当前高亮字段不为null,将原来的字段换成我们高亮的字段即可if (name != null){//获取高亮的片段Text[] fragments = name.fragments();//替换StringBuilder stringBuilder = new StringBuilder();for (Text text : fragments){stringBuilder.append(text);}sourceAsMap.put("name", stringBuilder.toString());}System.out.println(sourceAsMap.toString());}}
}