简介
官方文档地址:https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/
spring-data-elasticseach提供对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-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.6</version> </dependency> <!-- mybatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>
- 修改配置文件
spring.data.elasticsearch.cluster-name=my-application spring.data.elasticsearch.cluster-nodes=h120,h121,h122
-
ok配置完成,接下来可以通过操作es了。
repository
- 创建实体类
/** 指定indexname、 type、 数据分片数、 备份数*/ @Document(indexName = "goods", type = "goods", shards = 3, replicas = 2) public class Goods implements Serializable { private Integer id; @Field(type = FieldType.Text, index = true, store = false, analyzer = "ik_max_word", searchAnalyzer = "ik_max_word") private String name; private String productId; private String barcode; private Integer typeId;
指定indexname、type、分片、被分数, 默认@Document里的字段都会被索引, 在字段上用@Field指定字段类型、是否索引、是否存储、 索引时的analyzer、 搜索时的analyzer。
-
创建repository
@Repository public interface GoodsRepository extends ElasticsearchRepository<Goods, Integer>{ List<Goods> findByNameContains(String key, Pageable pageable); List<Goods> findByBarcodeContains(String key, Pageable pageable); }
-
在测试类中注入 mapper和repository
@Autowired GoodsMapper goodsMapper; @Autowired GoodsRepository goodsRepository;
mapper用于查询数据库数据、 repository写入es。
-
加载数据
@Test public void indexAllGoods(){ // 通过mapper从数据库查数据, repository写入es List<Goods> goodsList = goodsMapper.selectAll(); goodsRepository.saveAll(goodsList); }
-
查询数据,用repository中定义的接口
@Test public void findGoodsByName(){ List<Goods> goodsList; goodsList = goodsRepository.findByBarcodeContains("69329392", PageRequest.of(0, 10)); print(goodsList); goodsList = goodsRepository.findByNameContains("后刹", PageRequest.of(0, 10)); print(goodsList); goodsList = goodsRepository.findByNameContains("刹车片", PageRequest.of(0, 10)); print(goodsList); goodsList = goodsRepository.findByNameContains("后刹车片", PageRequest.of(0, 10)); print(goodsList); } private void print(List list){ System.out.println(JSONObject.toJSONString(list)); }
经过测试,这里查询后刹车片能查出,因为有名叫后刹车片的数据,刹车片却不能查出。 es对中文的模糊查询并不可靠,得事先优化IK的词库。 中文字段最好用Search。
-
搜索数据
@Test public void stringQueryBuilder(){ // QueryBuilder queryBuilder = new QueryStringQueryBuilder("name:刹车片"); // QueryBuilder queryBuilder = new QueryStringQueryBuilder("刹车片").field("name"); QueryBuilder queryBuilder = new QueryStringQueryBuilder("刹车片").field("name").analyzer("ik_max_word"); Iterable<Goods> goodsIterable = goodsRepository.search(queryBuilder); Iterator<Goods> iterator = goodsIterable.iterator(); while (iterator.hasNext()){ Goods goods = iterator.next(); System.out.println(JSONObject.toJSONString(goods)); } System.out.println("-------------------------"); queryBuilder = new QueryStringQueryBuilder("刹车片").field("name"); goodsIterable = goodsRepository.search(queryBuilder); iterator = goodsIterable.iterator(); while (iterator.hasNext()){ Goods goods = iterator.next(); System.out.println(JSONObject.toJSONString(goods)); } }
支持多种QueryBuilder。
ElasticsearchTemplate操作
直接注入ElasticsearchTemplate即可进行操作。