Java操作ES的方式
Elasticsearch提供了两种java语言操作elasticsearch的API,一种是Java Transport Client,一种是Java REST Client。Java REST Client又分为Java Low Level REST Client和Java High Level REST Client,Java High Level REST Client是在Java Low Level REST Client的基础上做了封装,使其以更加面向对象和操作更加便利的方式调用elasticsearch服务。
Spring Data也提供了操作Elasticsearch的模块:Spring Data Elasticsearch。本文主要介绍Spring Data Elasticsearch。Spring Data Elasticsearch提供了两种操作ES的方式,一种是通过ElasticsearchTemplate,一种是通过继承ElasticsearchRepository。
版本
需要注意的是不同的springboot版本对应不同的ES版本,比如我使用的springboot版本是2.1.4,对应的ES版本是6.4.3,Lucene版本是7.4.0。如果版本对应不上,会报错。
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
application.yml
spring:
data:
elasticsearch:
cluster-name: elasticsearch
cluster-nodes: 172.16.60.222:9300 # 程序连接es的端口号是9300
实体类注解
@Document(indexName = "menu", type = "docs", shards = 1, replicas = 0)
//indexName:索引库名称
//type:对应在索引库中的类型
//shards:分片数量,默认值为5
//replicas:副本数量,默认值为1
@Id
//标记id主键
@Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_max_word")
//type:字段类型,枚举:FieldType
//index:是否索引,布尔类型,默认是true
//store:是否存储,布尔类型,默认是false
//analyzer:分词器:ik_max_word:最细粒度拆分;ik_smart:粗粒度拆分。使用ik分词器需要先配置插件
//searchAnalyzer:查询时使用的分词器
使用ElasticsearchTemplate创建索引
@SpringBootTest
@RunWith(SpringRunner.class)
public class ElasticSearchTest {
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
@Autowired
private SysMenuService sysMenuService;
@Test
public void creatIndex() {
// 创建索引
elasticsearchTemplate.createIndex(SysMenu.class);
// 配置映射
elasticsearchTemplate.putMapping(SysMenu.class);
//通过elasticsearchTemplate批量写入索引
List<IndexQuery> data = new ArrayList<>();
for (SysMenu sysMenu : sysMenuService.list()) {
IndexQuery indexQuery = new IndexQueryBuilder()
.withId(String.valueOf(sysMenu.getMenuId()))
.withObject(sysMenu).build();
data.add(indexQuery);
}
elasticsearchTemplate.bulkIndex(data);
}
}
使用ElasticsearchRepository操作ES
继承ElasticsearchRepository
@Component
public interface SysMenuRepository extends ElasticsearchRepository<SysMenu, Long> {
}
使用SysMenuRepository查询
@Autowired
private SysMenuRepository sysMenuRepository;
@Test
public void matchQuery() {
//匹配查询,进行分词,包含菜单、管理的都会被查出来
MatchQueryBuilder queryBuilder = new MatchQueryBuilder("name", "菜单管理");
Iterable<SysMenu> search = sysMenuRepository.search(queryBuilder);
}
@Test
public void termQuery() {
//term是代表完全匹配,不进行分词,文档中必须包含整个搜索的词汇
//使用term要确定的是这个字段是否“被分析”(analyzed)
//例如:”菜单管理“分词后是["菜单","管理"],查询”菜单“、”管理“能查出来数据,查询“菜单管理”查询不到数据
TermQueryBuilder queryBuilder = new TermQueryBuilder("name", "管理");
Iterable<SysMenu> search = sysMenuRepository.search(queryBuilder);
}
@Test
public void boolQuery() {
//组合查询
QueryBuilder queryBuilder = QueryBuilders.boolQuery()
.should(QueryBuilders.termQuery("parentId", -1))
.should(QueryBuilders.matchQuery("name", "权限"));
Iterable<SysMenu> search = sysMenuRepository.search(queryBuilder);
}
@Test
public void rangeQuery() {
//范围查询
QueryBuilder queryBuilder = QueryBuilders.rangeQuery("menuId")
.from(1000)
.to(1500)
.includeLower(true) // 包含上界
.includeUpper(true); // 包含下界
Iterable<SysMenu> search = sysMenuRepository.search(queryBuilder);
}
@Test
public void pageQuery() {
// 分页查询
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
queryBuilder.withQuery(QueryBuilders.matchQuery("name", "菜单管理"));
// 初始化分页参数
int page = 0;
int size = 10;
// 设置分页参数
queryBuilder.withPageable(PageRequest.of(page, size));
// 执行搜索,获取结果
Page<SysMenu> items = sysMenuRepository.search(queryBuilder.build());
// 打印总条数
System.out.println(items.getTotalElements());
// 打印总页数
System.out.println(items.getTotalPages());
// 每页大小
System.out.println(items.getSize());
// 当前页
System.out.println(items.getNumber());
}
使用ElasticsearchTemplate操作ES
@Test
public void query() {
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//过滤
queryBuilder.withFilter(QueryBuilders.termQuery("parentId", -1));
//范围查询
NativeSearchQuery query = queryBuilder.withQuery(QueryBuilders.rangeQuery("menuId").from(1000).to(2000).includeUpper(true).includeLower(true)).build();
//列表查询
//List sysMenus = elasticsearchTemplate.queryForList(query, SysMenu.class);
//分页查询,从0页开始,每页5条数据
query.setPageable(PageRequest.of(0, 5));
AggregatedPage<SysMenu> sysMenus = elasticsearchTemplate.queryForPage(query, SysMenu.class);
log.warn("number:" + sysMenus.getNumber());
log.warn("size:" + sysMenus.getSize());
log.warn("totalPages:" + sysMenus.getTotalPages());
for (SysMenu sysMenu : sysMenus.getContent()) {
log.warn(sysMenu.getName());
}
}