前言
本文介绍在SpringBoot项目中如何使用Elasticsearch来实现搜索。
SpringBoot整合ES
添加依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
配置
#集群名称
spring.data.elasticsearch.cluster-name=elasticsearch
#es的地址和端口
spring.data.elasticsearch.cluster-nodes=192.168.7.188:9300
实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
//配置indexName索引名称,type是类型名称,shards是分片数,replicas是副本数
@Document(indexName = "goods",type = "_doc",shards = 1,replicas = 0)
public class Goods {
@Id
private Long id;
//配置字段,type是类型,analyzer是分词器,index是否索引
@Field(type = FieldType.Text,analyzer = "ik_max_word")
private String name;
@Field(type = FieldType.Keyword)
private String brand;
@Field(type = FieldType.Keyword)
private String categroy;
@Field(type = FieldType.Double)
private Double price;
}
使用ElasticsearchTemplate创建索引,添加映射
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = SearchServiceApplication.class)
public class ElasticsearchTest {
@Autowired
private ElasticsearchTemplate template;
@Test
public void createIndex(){
//删除索引
template.deleteIndex(Goods.class);
//创建索引
template.createIndex(Goods.class);
//添加映射,将字段映射到类型上
template.putMapping(Goods.class);
}
}
检查结果
操作索引
使用ElasticsearchRepository接口完成索引操作
/**
* goods索引操作接口
*/
public interface GoodsRepository extends ElasticsearchRepository<Goods,Long> {
}
测试添加数据
@Autowired
private GoodsRepository goodsRepository;
@Test
public void testSave(){
Goods goods = new Goods(1L, "华为P30手机", "Huawei", "手机", 4444.0);
//单条保存,id存在就更新,不存在就添加
goodsRepository.save(goods);
List<Goods> list = Arrays.asList(
new Goods(2L, "华为P40手机", "Huawei", "手机", 6666.0),
new Goods(3L, "小米11手机", "MI", "手机", 6666.0),
new Goods(4L, "小米12手机", "MI", "手机", 1666.0),
new Goods(5L, "小米13手机", "MI", "手机", 2666.0),
new Goods(6L, "OPPOX1手机", "oppo", "手机", 3666.0),
new Goods(7L, "OPPOX2手机", "oppo", "手机", 4666.0),
new Goods(8L, "OPPOX3手机", "oppo", "手机", 2666.0),
new Goods(9L, "VIVOv1手机", "vivo", "手机", 3666.0),
new Goods(10L, "VIVOv2手机", "vivo", "手机", 5666.0)
);
//多条保存
goodsRepository.saveAll(list);
}
查询数据
ElasticsearchRepository提供了非常强大的查询生成功能,按约定的方式在接口中定义查询方法,它来实现查询。
如:
/**
* goods索引操作接口
*/
public interface GoodsRepository extends ElasticsearchRepository<Goods,Long> {
//通过名称模糊查询
List<Goods> findByNameLike(String name);
//查询两个价格之间的商品
List<Goods> findByPriceBetween(Double p1,Double p2);
}
可以使用的关键字:
关键字 | 示例 |
---|---|
And | findByNameAndPrice |
Or | findByNameOrPrice |
Is | findByName |
Not | findByNameNot |
Between | findByPriceBetween |
LessThan | findByPriceLessThan |
LessThanEqual | findByPriceLessThanEqual |
GreaterThan | findByPriceGreaterThan |
GreaterThanEqual | findByPriceGreaterThan |
Before | findByPriceBefore |
After | findByPriceAfter |
Like | findByNameLike |
StartingWith | findByNameStartingWith |
EndingWith | findByNameEndingWith |
Contains/Containing | findByNameContaining |
In (when annotated as FieldType.Keyword) | findByNameIn(Collectionnames) |
In | findByNameIn(Collectionnames) |
NotIn (when annotated as FieldType.Keyword) | findByNameNotIn(Collectionnames) |
NotIn | findByNameNotIn(Collectionnames) |
Near | findByStoreNear |
True | findByAvailableTrue |
False | findByAvailableFalse |
OrderBy | findByAvailableTrueOrderByNameDesc |
测试
@Test
public void testFind(){
List<Goods> list = goodsRepository.findByNameLike("华为");
list.forEach(System.out::println);
List<Goods> list2 = goodsRepository.findByPriceBetween(3000.0, 5000.0);
list2.forEach(System.out::println);
}
测试其它查询方式
@Test
public void testSearch(){
//基本的搜索
MatchQueryBuilder builder = QueryBuilders.matchQuery("brand", "华为");
//查询结果
Iterable<Goods> goods = goodsRepository.search(builder);
goods.forEach(System.out::println);
//原生查询生成器
NativeSearchQueryBuilder builder1 = new NativeSearchQueryBuilder();
//生成原生查询
builder1
//.withQuery(QueryBuilders.termQuery("categroy","手机")) //精确查询
.withQuery(QueryBuilders.fuzzyQuery("brand","oppe")) //模糊查询,可以查到oppo
.withPageable(PageRequest.of(0,3)) //设置分页
.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC)); //配置排序
//查询结果
Page<Goods> page = goodsRepository.search(builder1.build());
System.out.println("total:"+page.getTotalElements());
System.out.println("page:"+page.getTotalPages());
page.getContent().forEach(System.out::println);
}
结束
大家如果需要学习其他Java知识点,戳这里 超详细的Java知识点汇总