索引 基本操作
package com.orchids.elasticsearch.web.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.orchids.elasticsearch.web.po.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
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.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.client.indices.GetIndexResponse;
import org.elasticsearch.cluster.metadata.MappingMetadata;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@Slf4j
@Api(tags = "索引")
@RestController
@RequestMapping("/elastic/index")
@RequiredArgsConstructor
public class ElasticIndexController {
private final RestHighLevelClient client;
static final String MAPPING_TEMPLATE = "{\n" +
" \"mappings\": {\n" +
" \"properties\": {\n" +
" \"name\":{\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\"\n" +
" },\n" +
" \"age\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"sex\":{\n" +
" \"type\": \"text\"\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
@ApiOperation("添加索引")
@PostMapping("/add")
public String CreateIndex(@RequestParam("index") String index) throws IOException {
CreateIndexRequest request = new CreateIndexRequest(index);
request.source(MAPPING_TEMPLATE, XContentType.JSON);
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
log.error("response{}",response);
if (response!=null){
return "add index success";
}else {
return "add index fail";
}
}
@ApiOperation("获取索引")
@GetMapping("/get")
public Map<String, Object> GetIndex(@RequestParam("index") String index) throws IOException {
GetIndexRequest request = new GetIndexRequest(index);
GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
if (client.indices().exists(request,RequestOptions.DEFAULT)){
MappingMetadata data = response.getMappings().get(index);
return data.getSourceAsMap();
}else {
return null;
}
}
@ApiOperation("查看映射")
@GetMapping("/mapper")
public Map<String, Object> Index(@RequestParam("index") String index) throws IOException {
GetIndexRequest request = new GetIndexRequest(index);
GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
Map<String, MappingMetadata> mappings = response.getMappings();
MappingMetadata metadata = mappings.get(index);
Map<String, Object> source = metadata.getSourceAsMap();
return source;
}
@ApiOperation("删除索引")
@DeleteMapping("/del")
public String DeleteIndex(@RequestParam("index") String index) throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest(index);
return client.indices().delete(request, RequestOptions.DEFAULT)!=null ? index+"删除成功" : index+"删除失败";
}
}
文档
package com.orchids.elasticsearch.web.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.orchids.elasticsearch.web.po.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.ElasticsearchStatusException;
import org.elasticsearch.action.bulk.BulkRequest;
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.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
@Slf4j
@Api(tags = "文档")
@RestController
@RequestMapping("/elastic/doc")
@RequiredArgsConstructor
public class ElasticDocumentController {
private final RestHighLevelClient client;
@ApiOperation("添加文档")
@PostMapping("/add")
public String addDocument(@RequestParam("index") String index, @RequestBody User user) throws IOException {
if (user==null) {
throw new RuntimeException("非法参数");
}
String jsonUser = JSONUtil.toJsonStr(user);
System.out.println(jsonUser);
IndexRequest request = new IndexRequest(index).id(user.getName());
request.source(jsonUser, XContentType.JSON);
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
if (response!=null){
return "success";
}else {
return "fail";
}
}
@ApiOperation("获取文档")
@GetMapping("/get")
public User getDocument(@RequestParam("id") String id,@RequestParam("index") String index) throws IOException {
GetRequest request = new GetRequest(index).id(id);
GetResponse response = client.get(request, RequestOptions.DEFAULT);
String jsonBean = response.getSourceAsString();
log.error("响应response{}",jsonBean);
User bean = JSONUtil.toBean(jsonBean, User.class);
System.out.println(bean);
return bean;
}
@ApiOperation("所有文档")
@GetMapping("/all")
public List<User> allDocument(@RequestParam String index) throws IOException {
SearchRequest request = new SearchRequest(index);
request.source().query(QueryBuilders.matchAllQuery());
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
return handleResponse(response);
}
private List<User> handleResponse(SearchResponse response) {
SearchHits searchHits = response.getHits();
long total = searchHits.getTotalHits().value;
log.error("一共搜索到{}条数据",total);
SearchHit[] hits = searchHits.getHits();
List<User> users = new LinkedList<>();
for (SearchHit hit : hits) {
String source = hit.getSourceAsString();
log.error("原始的json格式{}",source);
User user = JSONUtil.toBean(source, User.class);
log.error("放序列化后json格式{}",user);
users.add(user);
}
return users;
}
@ApiOperation("删除文档")
@DeleteMapping("/del")
public String updateDocument(@RequestParam("index") String index,@RequestParam("id")String id) throws IOException {
DeleteRequest request = new DeleteRequest(index,id);
DeleteResponse delete = client.delete(request, RequestOptions.DEFAULT);
if (delete!=null){
return "success";
}else {
return "fail";
}
}
@ApiOperation("修改文档")
@PostMapping("/update")
public String updateDocument(@RequestParam("index") String index,@RequestBody User user) throws IOException {
if (user.getName()==null) {
return "id参数非法";
}
UpdateRequest request = new UpdateRequest(index,user.getName());
request.doc("name",user.getName(),"age",user.getAge(),"sex",user.getSex());
try {
client.update(request, RequestOptions.DEFAULT);
} catch (ElasticsearchStatusException e) {
String jsonUser = JSONUtil.toJsonStr(user);
System.out.println(jsonUser);
IndexRequest req = new IndexRequest(index).id(user.getName());
req.source(jsonUser, XContentType.JSON);
client.index(req,RequestOptions.DEFAULT);
}
return "修改成功";
}
@ApiOperation("批量添加")
@PutMapping("/adds")
public String LoadDocument() throws IOException {
return "todo";
}
}
Java client
package com.orchids.elasticsearch.web.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.orchids.elasticsearch.web.po.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@Slf4j
@Api(tags = "Restapi")
@RestController
@RequestMapping("/elastic/rest")
@RequiredArgsConstructor
public class ElasticRestController {
private final RestHighLevelClient client;
public void testAgg() throws IOException {
SearchRequest request = new SearchRequest("items");
BoolQueryBuilder bool = QueryBuilders.boolQuery()
.filter(QueryBuilders.termQuery("category", "手机"))
.filter(QueryBuilders.rangeQuery("price").gte(300000));
request.source().query(bool).size(0);
request.source().aggregation(
AggregationBuilders.terms("brand_agg").field("brand").size(5)
);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
Aggregations aggregations = response.getAggregations();
Terms brandTerms = aggregations.get("brand_agg");
List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
for (Terms.Bucket bucket : buckets) {
String brand = bucket.getKeyAsString();
System.out.print("brand = " + brand);
long count = bucket.getDocCount();
System.out.println("; count = " + count);
}
}
@ApiOperation("高亮查询")
@GetMapping("/high")
public List<User> HighlightQuery(
@ApiParam(name = "index",value = "索引",required = true) @RequestParam("index")String index,
@ApiParam(name = "high",value = "高亮条件",required = true)@RequestParam("high") String high ) throws IOException {
SearchRequest request = new SearchRequest(index);
request.source().query(QueryBuilders.matchQuery("name", high));
request.source().highlighter(
SearchSourceBuilder.highlight()
.field("name")
.preTags("<em>")
.postTags("</em>")
);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
return hand(response);
}
private List<User> hand(SearchResponse response) {
SearchHits searchHits = response.getHits();
long total = searchHits.getTotalHits().value;
System.out.println("共搜索到" + total + "条数据");
SearchHit[] hits = searchHits.getHits();
List<User> result = new LinkedList<>();
for (SearchHit hit : hits) {
String source = hit.getSourceAsString();
User user = JSONUtil.toBean(source, User.class);
Map<String, HighlightField> hfs = hit.getHighlightFields();
if (CollUtil.isNotEmpty(hfs)) {
HighlightField hf = hfs.get("name");
if (hf != null) {
String hfName = hf.getFragments()[0].string();
user.setName(hfName);
}
}
result.add(user);
}
return result;
}
@ApiOperation("分页查询")
@GetMapping("/page")
public List <User> pageQuery(
@ApiParam(value = "索引",required = true)@RequestParam("index")String index,
@ApiParam(value = "字段条件",required = true)@RequestParam("field") String field,
@ApiParam(value = "当前页",required = true)@RequestParam("current")String current,
@ApiParam(value = "页大小",required = true)@RequestParam("size")String size) throws IOException {
SearchRequest request = new SearchRequest(index);
request.source().query(QueryBuilders.matchQuery("name", field));
request.source().sort("age", SortOrder.ASC);
request.source().from((Integer.valueOf(current) - 1) * Integer.valueOf(size)).size(Integer.valueOf(size));
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
return handleResponse(response);
}
private List <User> handleResponse(SearchResponse response) {
SearchHits searchHits = response.getHits();
long total = searchHits.getTotalHits().value;
System.out.println("共搜索到" + total + "条数据");
SearchHit[] hits = searchHits.getHits();
List<User> result = new LinkedList<>();
for (SearchHit hit : hits) {
String source = hit.getSourceAsString();
User user = JSONUtil.toBean(source, User.class);
result.add(user);
}
return result;
}
@ApiOperation("复合条件")
@GetMapping("/compare")
public List<User> compareQuery(
@ApiParam(value = "索引",required = true)@RequestParam("index") String index,
@ApiParam(value = "名称",required = true)@RequestParam ("name")String name,
@ApiParam(value = "性别",required = true)@RequestParam("sex") String sex,
@ApiParam(value = "年龄",required = true)@RequestParam("age") String age)throws IOException {
SearchRequest request = new SearchRequest(index);
BoolQueryBuilder bool = QueryBuilders.boolQuery();
if (name!=null){
bool.must(QueryBuilders.matchQuery("name", name));
}
if (sex!=null){
bool.filter(QueryBuilders.termQuery("sex", sex));
}
if (age!=null){
bool.filter(QueryBuilders.rangeQuery("age").gt(age));
}
request.source().query(bool);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
return handleResponse(response);
}
@ApiOperation("区间查询")
@GetMapping("/term")
public List<User> rangeQuery(
@ApiParam(value = "索引",required = true)@RequestParam String index,
@ApiParam(value = "左区间",required = true)@RequestParam("gt") String gt,
@ApiParam(value = "右区间",required = true)@RequestParam("lt") String lt,
@ApiParam(value = "支持排序的字段",required = true)@RequestParam("field") String field) throws IOException {
SearchRequest request = new SearchRequest(index);
request.source().query(QueryBuilders.rangeQuery(field).gte(gt).lte(lt));
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
return handleResponse(response);
}
@ApiOperation("多条件查询")
@GetMapping("/multi_match")
public List<User> multi_matchQuery(@ApiParam(value = "包含条件1" ,required = true)@RequestParam("name1") String args1,
@ApiParam(value = "包含条件2",required = true)@RequestParam("name2") String args2) throws IOException {
SearchRequest request = new SearchRequest("user");
request.source().query(QueryBuilders.multiMatchQuery("name",args1,args2));
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
return handleResponse(response);
}
@ApiOperation("match查询")
@GetMapping("/match")
public List<User> matchQuery(
@ApiParam(value = "索引",name = "index",required = true) @RequestParam("index")String index,
@ApiParam(value ="匹配字段",name = "field",required = true)@RequestParam("field") String field) throws IOException {
SearchRequest request = new SearchRequest(index);
request.source().query(QueryBuilders.matchQuery("name",field));
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
return handleResponse(response);
}
@ApiOperation("match-all查询")
@GetMapping("/match-all")
public List<User> SearchMatchAll(@ApiParam(value = "索引",name = "index",required = true) @RequestParam("index")String index) throws IOException {
SearchRequest request = new SearchRequest(index);
request.source().query(QueryBuilders.matchAllQuery());
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
return handleResponse(response);
}
}
Bean
package com.orchids.elasticsearch.web.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;
@Configuration
public class RestClientConfiguration {
@Bean
public RestHighLevelClient restHighLevelClient(){
return new RestHighLevelClient(RestClient.builder(HttpHost.create("http://localhost:9200")));
}
}
po
package com.orchids.elasticsearch.web.po;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@ApiModel(description = "索引库实体")
public class User implements Serializable {
@ApiModelProperty(value = "名字",name = "name",example = "二哈")
private String name;
@ApiModelProperty(value = "年龄",name = "age",example = "99")
private Integer age;
@ApiModelProperty(value = "性别",name = "sex",example = "男")
private String sex;
}
app
package com.orchids.elasticsearch;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class ElasticsearchApplication {
public static void main(String[] args) {
SpringApplication.run(ElasticsearchApplication.class, args);
}
}
配置类
server:
port: 8080
logging:
level:
web: info
pattern:
dateformat: HH:mm:ss:SSS
file:
path: "logs"
knife4j:
enable: true
openapi:
title: 接口文档
description: "接口文档"
email: [email protected]
concat: erha
url: https://www.orchids.love
version: v1.0.0
group:
default:
group-name: default
api-rule: package
api-rule-resources: com.orchids.elasticsearch.web
依赖
<?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>
<groupId>com.orchids</groupId>
<artifactId>elasticsearch</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>elasticsearch</name>
<description>elasticsearch</description>
<properties>
<java.version>1.8</java.version>
<elasticsearch.version>7.12.1</elasticsearch.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.7.12</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${elasticsearch.version}</version>
</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>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-json</artifactId>
<version>5.8.28</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.6</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.orchids.elasticsearch.ElasticsearchApplication</mainClass>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>