<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("172.16.91.10:9200")
.build();
return RestClients.create(clientConfiguration).rest();
}
}
SpringBoot提供了两种操作ES的客户端
@Document
(indexName=“products”, createIndex=true) 用在类上,表示为一个ES中的文档
@Id
标记在属性上,将对象的 id
字段映射成文档中的 _id
@Field
(type=FieldTpye.keyword) :表示索引中字段的类型
@Document(indexName = "product", createIndex = true)
public class Product {
@Id
private Integer id;
@Field(type = FieldType.Keyword)
private String title;
@Field(type = FieldType.Float)
private Double price;
@Field(type = FieldType.Text)
private String description;
//get set ...
}
public class ElasticSearchOptionsTest extends ElasticsearchApplicationTests{
private ElasticsearchOperations elasticsearchOperations;
@Autowired
public ElasticSearchOptionsTest(ElasticsearchOperations elasticsearchOperations){
this.elasticsearchOperations=elasticsearchOperations;
}
/**
* save:当文档id不存在时,新增文档;如果存在就修改文档
*/
@Test
public void testIndex(){
Product product=new Product();
product.setId(1);
product.setTitle("小浣熊干脆面");
product.setPrice(5.5);
product.setDescription("小浣熊干脆面真好吃");
elasticsearchOperations.save(product);
}
/**
* 查询一条文档
*/
@Test
public void queryIndex(){
Product product = elasticsearchOperations.get("1", Product.class);
System.out.println(product);
}
/**
* 查询所有
*/
@Test
public void queryAllIndex(){
SearchHits<Product> search = elasticsearchOperations.search(Query.findAll(), Product.class);
System.out.println("总分数: "+search.getMaxScore());
System.out.println("符合条件的条数: "+search.getTotalHits());
for (SearchHit<Product> searchHit : search) {
System.out.println(searchHit.getContent());
}
}
/**
* 删除一条文档
*/
@Test
public void testDelete(){
//根据Id删除
elasticsearchOperations.delete("1",Product.class);
//删除所有
elasticsearchOperations.delete(Query.findAll(),Product.class);
}
}
@Test
public void createIndex() throws IOException {
//创建索引请求,指定索引名
CreateIndexRequest createIndexRequest = new CreateIndexRequest("product");
//设置索引映射,参数1:json格式的映射结构 参数2:指定格式的类型(json)
createIndexRequest.mapping("{\n" +
" \"properties\": {\n" +
" \"title\":{\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"price\":{\n" +
" \"type\": \"double\"\n" +
" },\n" +
" \"create_at\":{\n" +
" \"type\": \"date\"\n" +
" },\n" +
" \"description\":{\n" +
" \"type\": \"text\"\n" +
" }\n" +
" }\n" +
" }", XContentType.JSON);
//参数1:创建索引请求 ,参数2:索引请求的配置对象,一般直接用默认的
//返回对象包含的索引的创建状态
CreateIndexResponse response = elasticsearchClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
//Acknowledged属性表示了索引是否创建成功
System.out.println(response.isAcknowledged());
}
/**
* 删除索引
*/
@Test
public void testDeleteIndex() throws IOException {
/*参数1:删除索引对象 参数2:请求配置对象*/
//返回操作结果
AcknowledgedResponse response = elasticsearchClient.indices().delete(new DeleteIndexRequest("product"), RequestOptions.DEFAULT);
System.out.println("删除结果:"+response.isAcknowledged());
}
/**
创建文档
*/
@Test
public void createDoc() throws IOException {
//创建请求索引对象,需要传入索引的名称
IndexRequest indexRequest = new IndexRequest("product");
//可指定id,不指定就UUID,一般传入 json格式的文档
indexRequest.id("1").source("{\n" +
" \"title\":\"红烧牛肉面\",\n" +
" \"price\":\"5.5\",\n" +
" \"create_at\":\"2022-04-13\",\n" +
" \"description\":\"红烧牛肉面真难吃\"\n" +
"}", XContentType.JSON);
//参数1: 索引的请求对象 ,参数2:请求配置对象
IndexResponse response = elasticsearchClient.index(indexRequest, RequestOptions.DEFAULT);
System.out.println(response.status());
}
/**
* 更新文档
*/
@Test
public void updateDoc() throws IOException {
//参数1:索引名,参数2:文档id
UpdateRequest updateRequest = new UpdateRequest("product","1");
updateRequest.doc("{\n" +
" \"description\":\"新:好饿想吃\"\n" +
" }",XContentType.JSON);
UpdateResponse response = elasticsearchClient.update(updateRequest, RequestOptions.DEFAULT);
System.out.println(response.status());
}
/**
* 删除文档
*/
@Test
public void deleteDoc() throws IOException{
//参数1:索引名,参数2:id值
DeleteRequest deleteRequest = new DeleteRequest("product","1");
DeleteResponse response = elasticsearchClient.delete(deleteRequest, RequestOptions.DEFAULT);
System.out.println(response.status());
}
/**
* 根据ID查询文档
*/
@Test
public void queryDoc() throws IOException {
GetRequest getRequest = new GetRequest("product","1");
GetResponse response = elasticsearchClient.get(getRequest, RequestOptions.DEFAULT);
System.out.println("ID:"+response.getId());
System.out.println("数据:"+response.getSourceAsString());
}
查询所有
/**
* 查询所有
*/
@Test
public void queryAll() throws IOException {
//指定搜索的索引
SearchRequest searchRequest = new SearchRequest("product");
//指定查询条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//查询所有
sourceBuilder.query(QueryBuilders.matchAllQuery());
searchRequest.source(sourceBuilder);
//参数1 :搜索的请求对象 参数2:请求配置对象
SearchResponse response = elasticsearchClient.search(searchRequest,RequestOptions.DEFAULT);
System.out.println("总记录数:"+response.getHits().getTotalHits().value);
System.out.println("最大得分:"+response.getHits().getMaxScore());
//获取结果
SearchHit[] hits = response.getHits().getHits();
for (SearchHit hit : hits) {
System.out.println("Id:"+hit.getId());
System.out.println("source:"+hit.getSourceAsString());
}
}
关键词查询
/**
* 不同条件查询 term(关键词查询)
*/
@Test
public void termQuery() throws IOException {
//指定搜索的索引
SearchRequest searchRequest = new SearchRequest("product");
//指定查询条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termQuery("description","吃"));
searchRequest.source(sourceBuilder);
SearchResponse response = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);
System.out.println("符合条件的数量:"+response.getHits().getTotalHits().value);;
System.out.println("获得文档最大分数:"+response.getHits().getMaxScore());;
SearchHit[] hits = response.getHits().getHits();
for (SearchHit hit : hits) {
System.out.println("id:"+hit.getId()+" source:"+hit.getSourceAsString());;
}
}
封装高级查询
public void queryBasic(QueryBuilder queryBuilder) throws IOException {
//指定搜索的索引
SearchRequest searchRequest = new SearchRequest("product");
//指定查询条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(queryBuilder);
searchRequest.source(sourceBuilder);
SearchResponse response = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);
System.out.println("符合条件的数量:"+response.getHits().getTotalHits().value);;
System.out.println("获得文档最大分数:"+response.getHits().getMaxScore());;
SearchHit[] hits = response.getHits().getHits();
for (SearchHit hit : hits) {
System.out.println("id:"+hit.getId()+" source:"+hit.getSourceAsString());;
}
}
/**
* 封装查询
* @throws IOException
*/
@Test
public void queryTest() throws IOException {
//1.term 关键词查询
queryBasic(QueryBuilders.termQuery("description","吃"));
//2.range 范围查询
queryBasic(QueryBuilders.rangeQuery("price").gt(0).lte(10));
//3.prefix 前缀查询
queryBasic(QueryBuilders.prefixQuery("description","红烧牛肉面"));
//4.wildcard 通配符查询 ?表示一个字符 *表示任意个字符
queryBasic(QueryBuilders.wildcardQuery("title","红烧*"));
//5.ids 多个指定id查询
queryBasic(QueryBuilders.idsQuery().addIds("1").addIds("2"));
//6.multi_math 多字段查询
queryBasic(QueryBuilders.multiMatchQuery("红烧","title","description"));
}
/*
1.关键字查询 term
2.分页查询 from size
3.排序 sort
4.返回指定的字段 fetchSource 用来指定查询返回的字段
*/
@SneakyThrows
@Test
public void queryLimit() throws IOException {
SearchRequest searchRequest = new SearchRequest("product");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//创建高亮器
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.requireFieldMatch(false).field("description").preTags("<span style='color:red;'>").postTags("</span>");
searchSourceBuilder.query(QueryBuilders.termQuery("description","面"))
.from(0) //起始位置 (page-1)*size
.size(1) //每页的数量
.sort("price", SortOrder.DESC) // 1.排序的字段 2.排序的方式
.fetchSource(new String[]{}, new String[]{"create_at"}) // 1.包含的字段 2.想要排除的字段
.highlighter(highlightBuilder); //高亮查询
searchRequest.source(searchSourceBuilder);
SearchResponse response = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);
System.out.println("符合条件的数量:" + response.getHits().getTotalHits().value);
System.out.println("获得文档最大分数:" + response.getHits().getMaxScore());
SearchHit[] hits = response.getHits().getHits();
for (SearchHit hit : hits) {
System.out.println("id:" + hit.getId() + " source:" + hit.getSourceAsString());
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
if (highlightFields.containsKey("description")) {
System.out.println("description高亮结果:" + highlightFields.get("description").fragments()[0]);
}
}
}
Java类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Snacks {
private Integer id;
private String title;
private Double price;
private String description;
}
测试
/*
将对象放入 ES中
*/
@Test
public void createIndex() throws IOException {
Snacks snacks = new Snacks();
snacks.setId(1);
snacks.setTitle("卫龙辣条");
snacks.setPrice(0.5);
snacks.setDescription("辣条真好吃");
IndexRequest indexRequest = new IndexRequest("snacks");
indexRequest.id(snacks.getId().toString())
//将对象转化为Json
.source(new ObjectMapper().writeValueAsString(snacks), XContentType.JSON);
IndexResponse response = elasticsearchClient.index(indexRequest, RequestOptions.DEFAULT);
System.out.println("创建结果:"+response.status());
}
@Test
public void queryTest() throws IOException {
SearchRequest searchRequest = new SearchRequest("snacks");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.requireFieldMatch(false).field("description").preTags("<span style='color:red;'>").postTags("</span>");
sourceBuilder.query(QueryBuilders.termQuery("description","好吃"))
.highlighter(highlightBuilder);
searchRequest.source(sourceBuilder);
SearchResponse response = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = response.getHits().getHits();
List<Snacks> list=new ArrayList<>();
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
//将json转换为对象
Snacks snacks = new ObjectMapper().readValue(hit.getSourceAsString(), Snacks.class);
//处理高亮
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
if (highlightFields.containsKey("description")){
snacks.setDescription(highlightFields.get("description").fragments()[0].toString());
}
list.add(snacks);
}
for (Snacks snacks : list) {
System.out.println(snacks);
}
}