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())); }