es自己提供的客户段难用,需要自己拼接json。这里我们使用spring提供的官方文档
版本
依赖
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.leyou.demo</groupId> <artifactId>es-demo</artifactId> <version>1.0-SNAPSHOT</version> <parent> <artifactId>spring-boot-starter-parent</artifactId> <groupId>org.springframework.boot</groupId> <version>2.0.4.RELEASE</version> <relativePath></relativePath> </parent> <dependencies> <!--es启动器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <!--测试启动器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <!--springboot的maven插件,可以把springboot工程打包为jar包,壳独立运行--> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
实体类 ,getset方法省略了
package com.leyou.pojo; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; //Document注解指定索引库名称,索引类型(表),分片数量,副本数量 @Document(indexName = "hello2",type = "item",shards = 1,replicas = 1) public class Item { @Field(type = FieldType.Long) //指定类型 @Id //表示作为id存储 Long id; @Field(type = FieldType.Text,analyzer = "ik_smart") String title; @Field(type =FieldType.Keyword ) String category; @Field(type = FieldType.Keyword) String brand; @Field(type = FieldType.Double) String price; @Field(type = FieldType.Keyword,index = false) String image; }
测试方法
package com.leyou.es; import com.leyou.pojo.Item; 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.elasticsearch.core.ElasticsearchTemplate; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class demo { @Autowired ElasticsearchTemplate elasticsearchTemplate; @Test public void testCreate(){ //索引库名称,类型,分片,副本通过在实体类加Document注解指定了 //创建索引库 elasticsearchTemplate.createIndex(Item.class); //映射关系 //也通过实体类注解FILED指定字段数据类型,Id注解指定作为id存储 //创建映射关系 elasticsearchTemplate.putMapping(Item.class); } }
通过kibana查看是否创建
删除索引方法:deleteIndex();
Elasticsearch对象的index方法,需要凭借字符串,复杂,一般用来做复杂的查询,聚合啥的
简单增删改的接口:
ElasticsearchRepository<T, ID extends Serializable>使用和通用mapper类似定义一个接口继承这个接口,
//泛型是实体类类型,Id类型 public interface ItemRepository extends ElasticsearchRepository<Item,Long> { }然后就可以直接用Autowired注解注入这个接口的对象使用了
插入:如果数据存在就会修改,id判断
save:增加一个
saveAll:批量新增
查询
自定义查询 :在接口中自己定义个方法,它会自动帮我们实现,我们可以直接使用(自定义方法),没提供聚合查询
package com.leyou.repository; import com.leyou.pojo.Item; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import java.util.List; //泛型是实体类类型,Id类型 public interface ItemRepository extends ElasticsearchRepository<Item,Long> { List<Item> findByPriceBetween(Double begin,Double end); //定义方法,他自己给我们实现了,直接调用 }还可以分页,通过定义方法时加pagealbe类型参数
官方文档
原理,根据方法名称生成查询添加。。。聚合查询只能用原生的了
1.使用接口的search方法,因为定义接口实已经指定了类型,所以不需要在指定了
Iterable<T> search(QueryBuilder query); Page<T> search(QueryBuilder query, Pageable pageable); Page<T> search(SearchQuery searchQuery);这个方法需要一个QueryBuilder类型对象,使用QueryBuilders工具类的静态方法来生成对应条件的QueryBuilder的实现类对象
QueryBuilder只能整合查询条件不能做结果过滤等等
@Test public void testFindBy(){ MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "小米手机"); //还有很多方法 Iterable<Item> search = itemRepository.search(matchQueryBuilder); search.forEach(s-> System.out.println(s)); }除了可以接受 QueryBuilder对象外还可以接受一个SearchQuery对象返回page对象:Page<T> search(SearchQuery searchQuery);
SearchQuery功能多:
public void testQuery(){ //1.创建查询构建器 NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder(); //2.添加查询条件 //添加查询条件,可以整合结果过滤啥的功能 nativeSearchQueryBuilder.withQuery(QueryBuilders.matchQuery("title", "小米手机")); //结果过滤 nativeSearchQueryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{"id","title","price"},null)); //排序 FieldSortBuilder price = SortBuilders.fieldSort("price").order(SortOrder.DESC); nativeSearchQueryBuilder.withSort(price); //分页 //当前页0开始,每页条数 nativeSearchQueryBuilder.withPageable(PageRequest.of(0,5)); //3.使用查询构建器构建查询添加并传给search方法获得page对象 Page<Item> search = itemRepository.search(nativeSearchQueryBuilder.build()); List<Item> content = search.getContent(); content.forEach(s-> System.out.println(s)); }
2.使用ElasticsearchTemplate的query相关方法,要指定返回类型(聚合查询用)
public void testAgg() { String aggName = "popularBrand"; NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder(); //添加聚合类型,聚合名称,聚合字段可以添加多个 nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms(aggName).field("brand")); //返回带聚合的结果 AggregatedPage<Item> result = elasticsearchTemplate.queryForPage(nativeSearchQueryBuilder.build(), Item.class); //解析,获得所有聚合 Aggregations aggregations = result.getAggregations(); //获得指定名称聚合 //聚合失败就获取不到 Aggregation aggregation = aggregations.get(aggName); //获取桶,上面的类型没有对应方法。要用StringTerms,因为我们分桶的字段类型是字符串类型的text StringTerms agg = (StringTerms) aggregation; //获取桶 List<StringTerms.Bucket> buckets = agg.getBuckets(); buckets.forEach(b-> System.out.println(b.getDocCount()+":"+b.getKeyAsString())); }