Spring-Data-ElasticSearch简单使用介绍
一.配置application.yaml文件:
spring:
data:
elasticsearch:
cluster-name: elasticsearch
cluster-nodes: 192.168.0.22:9300
二.实体类及注解
@Document(indexName = "goods",type = "docs", shards = 1, replicas = 0)
public class Item {
@Id
private Long id;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title; //标题
@Field(type = FieldType.Keyword)
private String category;// 分类
@Field(type = FieldType.Keyword)
private String brand; // 品牌
@Field(type = FieldType.Double)
private Double price; // 价格
@Field(index = false, type = FieldType.Keyword)
private String images; // 图片地址
与elasticsearch库进行映射
@Document作用在类,标记实体类为文档对象,一般有四个属性
--indexName:对应索引库名称
--type:对应在索引库中的类型
--shards:分片数量,默认5
--replicas:副本数量,默认1
@Id 作用在成员变量,标记一个字段作为id主键
@Field 作用在成员变量,标记为文档的字段,并指定字段映射属性:
--type:字段类型,取值是枚举:FieldType
--index:是否索引,布尔类型,默认是true
--store:是否存储,布尔类型,默认是false
--a-nalyzer:分词器名称:ik_max_word
三.具体使用:
1.创建索引和映射
@SpringBootTest
@RunWith(SpringRunner.class)
public class ElasticSearctTest {
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
@Test
public void testCreate() {
// 创建索引,会根据Item类的@Document注解信息来创建
elasticsearchTemplate.createIndex(Item.class);
// 配置映射,会根据Item类中的id、Field等字段来自动完成映射
elasticsearchTemplate.putMapping(Item.class);
}
2.增删改查方法
@Autowired
private ItemRepository itemRepository;
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
//添加
@Test
public void testAdd() {
Item item = new Item(1L, "小米手机7", " 手机","小米", 3499.00, "http://image.leyou.com/13123.jpg");
itemRepository.save(item);
//批量添加
List<Item> list = new ArrayList<>();
list.add(new Item(2L, "坚果手机R1", " 手机", "锤子", 3699.00, "http://image.leyou.com/123.jpg"));
list.add(new Item(3L, "华为META10", " 手机", "华为", 4499.00, "http://image.leyou.com/3.jpg"));
itemRepository.saveAll(list);
}
//修改(因为添加修改是根据id进行的,所以id存在就是修改,否则就是添加 )
@Test
public void testUpdate() {
Item item = new Item(1L, "小米手机7777", " 手机", "小米", 9499.00, "http://image.leyou.com/13123.jpg");
itemRepository.save(item);
}
//删除与查询
@Test
public void testDelete() {
itemRepository.deleteById(1L);
Optional<Item> optional = itemRepository.findById(2L);
}
3.普通查询
@Test
public void tes1() {
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "手机");
Iterable<Item> search = itemRepository.search(matchQueryBuilder);
search.forEach(System.out::println);
}
4. 自定义方法
Spring Data 的另一个强大功能,是根据方法名称自动实现功能。
比如:你的方法名叫做:findByTitle,那么它就知道你是根据title查询,然后自动帮你完成,无需写实现类。
但是要根据他的规则去写(会有提示) 如:
public interface ItemRepository extends ElasticsearchRepository<Item,Long> {
/**
* 根据价格区间查询
* @param price1
* @param price2
* @return
*/
List<Item> findByPriceBetween(double price1, double price2);
}
5.分页查询,并排序
@Test
public void Page() {
// 构建查询条件
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
// 添加基本的分词查询
queryBuilder.withQuery(QueryBuilders.matchQuery("category", "手机"));
// 设置分页参数
queryBuilder.withPageable(PageRequest.of(0, 5));
// 执行搜索,并进行降序排序
queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.ASC));
Page<Item> itemPage = itemRepository.search(queryBuilder.build());
// 打印总条数
System.out.println(itemPage.getTotalPages());
// 打印总页数
System.out.println(itemPage.getTotalElements());
itemPage.forEach(System.out::println);
}
6.聚合查询
Repository: 操作库的对象
ItemRepository::用来操作item索引的对象
//Long是主键id的类型
public interface ItemRepository extends ElasticsearchRepository<Item,Long>
NativeSearchQueryBuilder: 本机搜索查询生成器,用来构建自己的查询语句
ItemRepository.search: 用来查询所有,相当于GET /goods/_search
Aggregation: 聚合对象
FetchSourceFilter: 获取源过滤器
Bucket: 桶
①根据brand进行分类
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
@Autowired
ItemRepository itemRepository;
@Test
public void testAgg() {
//构建自定义查询构建器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//添加聚合查询,AggregationBuilders工具类构建聚合
queryBuilder.addAggregation(AggregationBuilders.terms("brands").field("brand"));
//添加结果集过滤,不包含任何字段,也就是不需要普通结果集
queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{}, null));
//执行聚合查询,获取聚合结果集,需要强转
AggregatedPage<Item> itemPage = (AggregatedPage<Item>) itemRepository.search(queryBuilder.build());
//获取聚合结果集中的聚合对象:根据聚合名称获取想要获取的聚合对象.强转成子类:LongTerms StringTerms DoubleTerms
StringTerms brands = (StringTerms) itemPage.getAggregation("brands");
//获取聚合中的桶
brands.getBuckets().forEach(bucket -> {
//获取桶中的key
System.out.println(bucket.getKeyAsString());
//获取桶中的记录数
System.out.println(bucket.getDocCount());
});
}
②根据brand进行分类,添加子聚合avg计算每类price平均价格
@Test
public void testSubAgg() {
//构建自定义查询构建器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//添加聚合查询,AggregationBuilders工具类构建聚合
queryBuilder.addAggregation(AggregationBuilders.terms("brands").field("brand")
.subAggregation(AggregationBuilders.avg("price_avg").field("price")));
//添加结果集过滤,不包含任何字段,也就是不需要普通结果集
queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{}, null));
//执行聚合查询,获取聚合结果集,需要强转
AggregatedPage<Item> itemPage = (AggregatedPage<Item>) this.itemRepository.search(queryBuilder.build());
//获取聚合结果集中的聚合对象:根据聚合名称获取想要获取的聚合对象.强转成子类:LongTerms StringTerms DoubleTerms
StringTerms brandAgg = (StringTerms) itemPage.getAggregation("brands");
//获取聚合中的桶
brandAgg.getBuckets().forEach(bucket -> {
//获取桶中的key
System.out.println(bucket.getKeyAsString());
//获取桶中的记录数
System.out.println(bucket.getDocCount());
//解析子聚合,把子聚合结果集转成map结构,key-聚合名称,value-聚合对象 Map<price_avg,aggregation>
Map<String, Aggregation> stringAggregationMap = bucket.getAggregations().asMap();
InternalAvg price_avg = (InternalAvg) stringAggregationMap.get("price_avg");
System.out.println(price_avg.getValue());
});