0.准备
导入elasticsearch依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
1、配置application.properties连接远程elasticsearch
spring.data.elasticsearch.cluster-name=docker-cluster
spring.data.elasticsearch.cluster-nodes=106.54.196.44:9300
2、Blog实体类
package com.neo.model;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import java.util.Date;
@Document(indexName = "blog", type = "blog", shards = 1, replicas = 0, refreshInterval = "-1")
public class Blog {
//Id注解加上后,在Elasticsearch里相应于该列就是主键了,在查询时就可以直接用主键查询
@Id
private String id;
private String title;
private String content;
private Integer readTimes;
private String commentTimes;
private Integer typeId;
private Integer bloggerId;
private Date createTime;
private Date updateTime;
private Integer zan;
private Boolean hot;
private String type;
private Boolean isDelete;
public Blog() {
}
public Blog(String id, String title, String content, Integer readTimes, String commentTimes, Integer typeId, Integer bloggerId, Date createTime, Date updateTime, Integer zan, Boolean hot, String type, Boolean isDelete) {
this.id = id;
this.title = title;
this.content = content;
this.readTimes = readTimes;
this.commentTimes = commentTimes;
this.typeId = typeId;
this.bloggerId = bloggerId;
this.createTime = createTime;
this.updateTime = updateTime;
this.zan = zan;
this.hot = hot;
this.type = type;
this.isDelete = isDelete;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Integer getReadTimes() {
return readTimes;
}
public void setReadTimes(Integer readTimes) {
this.readTimes = readTimes;
}
public String getCommentTimes() {
return commentTimes;
}
public void setCommentTimes(String commentTimes) {
this.commentTimes = commentTimes;
}
public Integer getTypeId() {
return typeId;
}
public void setTypeId(Integer typeId) {
this.typeId = typeId;
}
public Integer getBloggerId() {
return bloggerId;
}
public void setBloggerId(Integer bloggerId) {
this.bloggerId = bloggerId;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public Integer getZan() {
return zan;
}
public void setZan(Integer zan) {
this.zan = zan;
}
public Boolean getHot() {
return hot;
}
public void setHot(Boolean hot) {
this.hot = hot;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Boolean getDelete() {
return isDelete;
}
public void setDelete(Boolean delete) {
isDelete = delete;
}
@Override
public String toString() {
return "Blog{" +
"id='" + id + '\'' +
", title='" + title + '\'' +
", content='" + content + '\'' +
", readTimes=" + readTimes +
", commentTimes='" + commentTimes + '\'' +
", typeId=" + typeId +
", bloggerId=" + bloggerId +
", createTime=" + createTime +
", updateTime=" + updateTime +
", zan=" + zan +
", hot=" + hot +
", type='" + type + '\'' +
", isDelete=" + isDelete +
'}';
}
}
3、创建repository类操作elasticsearch
package com.neo.repository;
import com.neo.model.Blog;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import java.util.List;
public interface BlogRepository extends ElasticsearchRepository<Blog, String> {
Page<Blog> findBlogsByTitle(String title, Pageable pageable);
List<Blog> findBlogsByTitle(String title);
Blog findBlogById(Integer id);
}
4、测试
package com.neo.repository;
import com.neo.model.Blog;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.metrics.sum.InternalSum;
import org.elasticsearch.search.aggregations.metrics.sum.SumAggregationBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.ResultsExtractor;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest
public class BlogRepositoryTest {
@Autowired
private BlogRepository repository;
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
/**
* 博客的添加
*/
@Test
public void saveBlog() {
Blog newBlog = new Blog();
newBlog.setTitle("title");
newBlog.setContent("content");
repository.save(newBlog);
}
/**
* 查询所有博客
*/
@Test
public void fetchAllBlog() {
System.out.println("Blog found with findAll():");
System.out.println("-------------------------------");
Iterable<Blog> iterable=repository.findAll();
for (Blog blog :iterable) {
System.out.println(blog);
}
}
/**
* 删除所有博客
*/
@Test
public void deleteBlog() {
repository.deleteAll();
}
/**
* 更新博客
*/
@Test
public void updateBlog() {
System.out.println("更新前--------------------");
Blog blog = repository.findBlogById(532);
System.out.println(blog);
blog.setTitle("自定义starter启动器(更新)");
repository.save(blog);
System.out.println("更新后--------------------");
Blog xblog=repository.findBlogById(532);
System.out.println(xblog);
}
/**
* 根据title获取博客
*/
@Test
public void fetchBlogByTitle() {
System.out.println("Blog found with findBlogsByTitle('springboot'):");
System.out.println("--------------------------------");
System.out.println(repository.findBlogsByTitle("springboot"));
System.out.println("--------------------------------");
System.out.println("Blog found with findBlogsByTitle(\"springboot\"):");
String title="springboot";
for (Blog blog : repository.findBlogsByTitle(title)) {
System.out.println(blog);
}
}
/**
* 分页查询
*/
@Test
public void fetchPageBlog() {
System.out.println("Blog found with fetchPageBlog:");
System.out.println("-------------------------------");
Sort sort = new Sort(Sort.Direction.DESC, "id");
Pageable pageable = PageRequest.of(0, 100, sort);
Page<Blog> blog=repository.findBlogsByTitle("springboot", pageable);
System.out.println("Page Blog "+blog.getContent().toString());
System.out.println("Page Total " + blog.getContent().size());
}
/**
* QueryBuilder构建查询 + 分页查询
*/
@Test
public void fetchPage2Blog() {
System.out.println("Blog found with fetchPageBlog:");
System.out.println("-------------------------------");
QueryBuilder blogQuery = QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("title", "springboot"));
Page<Blog> page = repository.search(blogQuery, PageRequest.of(0, 10));
System.out.println("Page blog "+page.getContent().toString());
System.out.println("Page Total " + page.getContent().size());
page = repository.search(blogQuery, PageRequest.of(1, 10));
System.out.println("Page blog "+page.getContent().toString());
System.out.println("Page Total " + page.getContent().size());
}
/**
* 聚合查询 计算查询结果的所有浏览量之和
*/
@Test
public void fetchAggregation() {
System.out.println("Blog found with fetchAggregation:");
System.out.println("-------------------------------");
QueryBuilder customerQuery = QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("title", "springboot"));
SumAggregationBuilder sumBuilder = AggregationBuilders.sum("sumReadTimes").field("readTimes");
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(customerQuery)
.addAggregation(sumBuilder)
.build();
Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {
@Override
public Aggregations extract(SearchResponse response) {
return response.getAggregations();
}
});
//转换成map集合
Map<String, Aggregation> aggregationMap = aggregations.asMap();
//获得对应的聚合函数的聚合子类,该聚合子类也是个map集合,里面的value就是桶Bucket,我们要获得Bucket
InternalSum sumReadTimes = (InternalSum) aggregationMap.get("sumReadTimes");
System.out.println("sum ReadTimes is "+sumReadTimes.getValue());
}
}
5、查询
精确查询
单个匹配:
//不分词查询 参数1: 字段名,参数2:字段查询值,因为不分词,所以汉字只能查询⼀个字,英语是⼀个单词
QueryBuilder queryBuilder=QueryBuilders.termQuery("fieldName", "fieldlValue");
//分词查询,采⽤默认的分词器
QueryBuilder queryBuilder2 = QueryBuilders.matchQuery("fieldName", "fieldlValue");
多个匹配:
//不分词查询,参数1:字段名,参数2:多个字段查询值,因为不分词,因此汉字只能查询⼀个字,英语是⼀个单词
QueryBuilder queryBuilder=QueryBuilders.termsQuery("fieldName", "fieldlValue1","fieldlValue2...");
//分词查询,采⽤默认的分词器
QueryBuilder queryBuilder= QueryBuilders.multiMatchQuery("fieldlValue", "fieldName1", "fieldName2", "fieldName3");
//匹配所有⽂件,相当于就没有设置查询条件
QueryBuilder queryBuilder=QueryBuilders.matchAllQuery();
模糊查询
//1.常⽤的字符串查询 QueryBuilders.queryStringQuery("fieldValue").field("fieldName");
//左右模糊 //2.常⽤的⽤于推荐相似内容的查询 QueryBuilders.moreLikeThisQuery(new String[] {"fieldName"}).addLikeText("pipeidhua");
//如果不指定filedName,则默认全部,常⽤在相似内容的推荐上 //3.前缀查询,如果字段没分词,就匹配整个字段前缀 QueryBuilders.prefixQuery("fieldName","fieldValue"); //4.fuzzy query:分词模糊查询,通过增加 fuzziness 模糊属性来查询,如能够匹配 hotelName 为 te l 前或后加⼀个字⺟的⽂档,fuzziness 的含义是检索的 term 前后增加或减少 n 个单词的匹配查询 QueryBuilders.fuzzyQuery("hotelName", "tel").fuzziness(Fuzziness.ONE); //5.wildcard query:通配符查询,⽀持* 任意字符串;?任意⼀个字符 QueryBuilders.wildcardQuery("fieldName","ctr*");
//前⾯是fieldname,后⾯是带匹配字符的字符串 QueryBuilders.wildcardQuery("fieldName","c?r?");
范围查询
//闭区间查询
QueryBuilder queryBuilder0 = QueryBuilders.rangeQuery("fieldName").from("fieldValu
e1").to("fieldValue2");
//开区间查询
QueryBuilder queryBuilder1 = QueryBuilders.rangeQuery("fieldName").from("fieldValu
e1").to("fieldValue2").includeUpper(false).includeLower(false);//默认是 true,也就是
包含
//⼤于
QueryBuilder queryBuilder2 = QueryBuilders.rangeQuery("fieldName").gt("fieldValue");
//⼤于等于
QueryBuilder queryBuilder3 = QueryBuilders.rangeQuery("fieldName").gte("fieldValue");
//⼩于
QueryBuilder queryBuilder4 = QueryBuilders.rangeQuery("fieldName").lt("fieldValue");
//⼩于等于
QueryBuilder queryBuilder5 = QueryBuilders.rangeQuery("fieldName").lte("fieldValue");