maven坐标
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<properties>
<!--需要指定es的版本,与服务的一致-->
<elasticsearch.version>7.15.0</elasticsearch.version>
</properties>
配置
package net.test.springbootweb.es;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Desc:ElasticsearchConfig
* Date:2021/12/13
*
* @author author
*/
@Configuration
public class ElasticsearchConfig {
@Bean
public RestHighLevelClient restHighLevelClient() {
HttpHost httpHost = HttpHost.create("http://127.0.0.1:9200");
RestClientBuilder restClientBuilder = RestClient.builder(httpHost);
return new RestHighLevelClient(restClientBuilder);
}
}
服务
https://www.elastic.co/cn/downloads/past-releases#elasticsearch https://github.com/medcl/elasticsearch-analysis-ik/releases
- ik分词解压到${esPath}/plugins下,压缩包不能放在该目录下,否则启动不起来
- ${esPath}/bin下启动服务,访问
http://localhost:9200/ ,出现JSON信息
测试entity类
package net.test.springbootweb.es;
import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.time.LocalDateTime;
/**
* Desc:EsEntity
* Date:2021/12/15
*
* @author author
*/
@Data
public class EsEntity {
@Field(type = FieldType.Keyword, analyzer = "ik_smart")
private String name;
@Field(type = FieldType.Keyword, analyzer = "ik_max_word")
private String description;
private LocalDateTime createTime;
public EsEntity() {
this.createTime = LocalDateTime.now();
}
}
测试索引
package net.test.springbootweb.es;
import com.alibaba.fastjson.JSONObject;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.GetAliasesResponse;
import org.elasticsearch.client.IndicesClient;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.Set;
/**
* 索引操作需要使用:IndicesClient indices = restHighLevelClient.indices();
* 创建:对象 CreateIndexRequest,方法 create
* 删除:对象 DeleteIndexRequest,方法 delete
* 获取:对象 GetIndexRequest,方法 get/exists
* 列表:对象 GetAliasesRequest,方法 getAlias
* Date:2021/12/14
*
* @author author
*/
@RestController
@RequestMapping("es")
public class ElasticsearchIndexTest {
@Autowired
private RestHighLevelClient restHighLevelClient;
/**
* 创建索引
*
* @param index
*/
@RequestMapping("createEsIndex")
public String createEsIndex(String index) throws IOException {
//特殊字符直接报错,包含英文逗号(, \", *, \\, <, |, ,, >, /, ?)
if (existsEsIndex(index)) {
return "index already exists";
}
CreateIndexRequest createIndexRequest = new CreateIndexRequest(index);
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
return JSONObject.toJSONString(createIndexResponse);
}
/**
* 删除索引
*
* @param indices
*/
@RequestMapping("deleteEsIndex")
public String deleteEsIndex(String... indices) throws IOException {
if (notExistsEsIndex(indices)) {
return "index does not exist";
}
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indices);
AcknowledgedResponse delete = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
return JSONObject.toJSONString(delete);
}
/**
* 获取所有索引
*
* @return
*/
@RequestMapping("getAllEsIndex")
public Set<String> getAllEsIndex() throws IOException {
GetAliasesRequest getAliasesRequest = new GetAliasesRequest();
GetAliasesResponse alias = restHighLevelClient.indices().getAlias(getAliasesRequest, RequestOptions.DEFAULT);
return alias.getAliases().keySet();
}
/**
* 判断索引是否存在
*
* @param indices
* @return
*/
public boolean existsEsIndex(String... indices) throws IOException {
GetIndexRequest getIndexRequest = new GetIndexRequest(indices);
return restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
}
/**
* 判断索引是否不存在
*
* @param indices
* @return
*/
public boolean notExistsEsIndex(String... indices) throws IOException {
return !existsEsIndex(indices);
}
}
测试文档
package net.test.springbootweb.es;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
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.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.client.core.CountResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* 文档操作直接使用:RestHighLevelClient
* 创建:对象 IndexRequest,方法 index
* 更新:对象 UpdateRequest,方法 update
* 删除:对象 DeleteRequest,方法 delete
* 获取:对象 GetRequest,方法 get/exists
* 批量:对象 BulkRequest,方法 bulk
* 数量:对象 CountRequest,方法 count
* 搜索:对象 SearchRequest,方法 search
* Date:2021/12/15
*
* @author author
*/
@RestController
@RequestMapping("es")
public class ElasticsearchDocumentTest {
@Autowired
private ElasticsearchIndexTest elasticsearchIndexTest;
@Autowired
private RestHighLevelClient restHighLevelClient;
/**
* 创建文档
*
* @param index
*/
@RequestMapping("createDocument")
public String createDocument(String index, String name, String description) throws IOException {
if (elasticsearchIndexTest.notExistsEsIndex(index)) {
return "index does not exist";
}
if (StringUtils.isAnyBlank(name, description)) {
return "name or description can not be empty";
}
EsEntity esEntity = new EsEntity();
esEntity.setName(name);
esEntity.setDescription(description);
IndexRequest indexRequest = new IndexRequest(index);
// indexRequest.id("111");//可以设置ID,也可以不设置自动生成
indexRequest.source(JSONObject.toJSONString(esEntity), XContentType.JSON);
IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
return "ID=" + response.getId() + ",INDEX=" + response.getIndex();
}
/**
* 批量创建文档
*
* @param index
* @param entityStr [{name:"名称",description:"描述"}]
* @return
*/
@RequestMapping("batchCreateDocument")
public String[] batchCreateDocument(String index, String entityStr) throws IOException {
if (elasticsearchIndexTest.notExistsEsIndex(index)) {
return new String[]{"index does not exist"};
}
List<EsEntity> esEntities = JSONArray.parseArray(entityStr, EsEntity.class);
BulkRequest bulkRequest = new BulkRequest().timeout(new TimeValue(10, TimeUnit.SECONDS));
for (EsEntity entity : esEntities) {
IndexRequest indexRequest = new IndexRequest(index);
indexRequest.source(JSONObject.toJSONString(entity), XContentType.JSON);
bulkRequest.add(indexRequest);
}
String[] arr = new String[esEntities.size()];
BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
BulkItemResponse[] items = bulk.getItems();
for (int i = 0; i < items.length; i++) {
DocWriteResponse response = items[i].getResponse();
arr[i] = "ID=" + response.getId() + ",INDEX=" + response.getIndex();
}
return arr;
}
/**
* 更新文档
*
* @param index
* @param id
* @return
*/
@RequestMapping("updateDocument")
public String updateDocument(String index, String id, String name, String description) throws IOException {
if (notExistDocument(index, id)) {
return "INDEX=" + index + ",DOC_ID=" + id + ",data does not exist";
}
UpdateRequest updateRequest = new UpdateRequest(index, id);
//只修改传值(不为null)的字段,值相同不进行修改
EsEntity esEntity = new EsEntity();
esEntity.setName(name);
esEntity.setDescription(description);
updateRequest.doc(JSONObject.toJSONString(esEntity), XContentType.JSON);
UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
return JSONObject.toJSONString(update);
}
/**
* 删除文档
*
* @param index
* @param id
* @return
*/
@RequestMapping("deleteDocument")
public String deleteDocument(String index, String id) throws IOException {
if (notExistDocument(index, id)) {
return "INDEX=" + index + ",DOC_ID=" + id + ",data does not exist";
}
DeleteRequest deleteRequest = new DeleteRequest(index, id);
DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
return JSONObject.toJSONString(delete);
}
/**
* 批量删除文档
*
* @param index
* @param ids
* @return
*/
@RequestMapping("batchDeleteDocument")
public String[] batchDeleteDocument(String index, String... ids) throws IOException {
if (elasticsearchIndexTest.notExistsEsIndex(index)) {
return new String[]{"index does not exist"};
}
BulkRequest bulkRequest = new BulkRequest();
for (String id : ids) {
DeleteRequest deleteRequest = new DeleteRequest(index, id);
bulkRequest.add(deleteRequest);
}
BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
String[] arr = new String[ids.length];
BulkItemResponse[] items = bulk.getItems();
for (int i = 0; i < items.length; i++) {
arr[i] = JSONObject.toJSONString(items[i].getResponse());
}
return arr;
}
/**
* 根据索引与ID获取文档
*
* @param index
* @param id
* @return
*/
@RequestMapping("getDocument")
public JSONObject getDocument(String index, String id) throws IOException {
GetRequest getRequest = new GetRequest(index, id);
if (notExistDocument(getRequest)) {
throw new RuntimeException("INDEX=" + index + ",DOC_ID=" + id + ",data does not exist");
}
GetResponse response = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
JSONObject obj = JSONObject.parseObject(JSONObject.toJSONString(response.getSource()));
obj.put("_id", response.getId());
obj.put("_index", response.getIndex());
return obj;
}
/**
* 查询INDEX的文档
*
* @param indices
* @return
*/
@RequestMapping("getAllDocument")
public JSONArray getAllDocument(@RequestParam(value = "page", defaultValue = "1") int page,
@RequestParam(value = "size", defaultValue = "5") int size,
String... indices) throws IOException {
CountRequest countRequest = new CountRequest();
SearchRequest searchRequest = new SearchRequest();
if (indices != null && indices.length > 0) {
if (elasticsearchIndexTest.notExistsEsIndex(indices)) {
throw new RuntimeException("indices does not exists");
}
searchRequest.indices(indices);
countRequest.indices(indices);
}
CountResponse countResponse = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
long count = countResponse.getCount();
JSONArray array = new JSONArray();
if (count > 0) {
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//分页
size = size <= 0 ? 5 : size;
sourceBuilder.from((Math.max(1, page) - 1) * size);
sourceBuilder.size(size);
// sourceBuilder.sort("_id", SortOrder.DESC);
//内容字段自定义排序(有些字段需要加.keyword)
sourceBuilder.sort(new FieldSortBuilder("createTime").order(SortOrder.DESC));
searchRequest.source(sourceBuilder);
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = search.getHits().getHits();
for (SearchHit hit : hits) {
JSONObject obj = new JSONObject(hit.getSourceAsMap());
obj.put("_id", hit.getId());
obj.put("_index", hit.getIndex());
array.add(obj);
}
}
return array;
}
/**
* 搜索文档
*
* @param indices
*/
@RequestMapping("searchDocument")
public JSONArray searchDocument(String search, String... indices) throws IOException {
if (elasticsearchIndexTest.notExistsEsIndex(indices)) {
throw new RuntimeException("indices does not exists");
}
SearchRequest searchRequest = new SearchRequest(indices);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.from(0);
sourceBuilder.size(100);
sourceBuilder.sort(new FieldSortBuilder("createTime").order(SortOrder.DESC));
//高亮显示
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("description");
highlightBuilder.requireFieldMatch(true);//仅查询此字段时才高亮,默认是false
highlightBuilder.preTags("<span style='color:red;'>");
highlightBuilder.postTags("</span>");
sourceBuilder.highlighter(highlightBuilder);
// TermQueryBuilder queryBuilder = QueryBuilders.termQuery("name.keyword", search);//精准查询
// WildcardQueryBuilder queryBuilder = QueryBuilders.wildcardQuery("name.keyword", "*" + search + "*");//模糊搜索
// MultiMatchQueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(search, "key1", "key2", "key3");//多字段查询
//ik_smart ik_max_word
MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("description", search);
sourceBuilder.query(queryBuilder);
searchRequest.source(sourceBuilder);
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = response.getHits().getHits();
JSONArray array = new JSONArray();
for (SearchHit hit : hits) {
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
HighlightField description = highlightFields.get("description");
if (description != null) {
//将高亮包含标签的内容容替换普通内容
StringBuilder newText = new StringBuilder();
for (Text fragment : description.getFragments()) {
newText.append(fragment);
}
sourceAsMap.put("description", newText.toString());
}
JSONObject obj = new JSONObject(sourceAsMap);
obj.put("_id", hit.getId());
obj.put("_index", hit.getIndex());
array.add(obj);
}
return array;
}
/**
* 判断数据是否存在
*
* @param index
* @param id
* @return
*/
public boolean existDocument(String index, String id) throws IOException {
GetRequest getRequest = new GetRequest(index, id);
return restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
}
/**
* 判断数据是否存在
*
* @param request
* @return
*/
public boolean existDocument(GetRequest request) throws IOException {
return restHighLevelClient.exists(request, RequestOptions.DEFAULT);
}
/**
* 判断数据是否不存在
*
* @param index
* @param id
* @return
*/
public boolean notExistDocument(String index, String id) throws IOException {
return !existDocument(index, id);
}
/**
* 判断数据是否不存在
*
* @param request
* @return
*/
public boolean notExistDocument(GetRequest request) throws IOException {
return !existDocument(request);
}
}
|