最近公司的项目用elk日志管理,用了下,感觉很不错,多个服务,生成很多的日志,在里面的查询速度相当可观。就想来学习下Elasticsearch。
但是spring boot 和Elasticsearch 都有很多的版本,版本兼容是个问题。我自己试了很多次,也想用最新的版本来学习,毕竟新版本的功能更好。
我最终测试成功spring boot 2.1.4RELEASE版本,Elasticsearch是6.7.1
1,准备工作,先去 Elasticsearch官网下载对应的版本,并本地安装,安装完成,访问http:localhost:9200,出现下面,就是安装成功了:
{
"name" : "node-1",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "_xXJF0WPT5ypv6hU35T_mA",
"version" : {
"number" : "6.7.1",
"build_flavor" : "default",
"build_type" : "zip",
"build_hash" : "2f32220",
"build_date" : "2019-04-02T15:59:27.961366Z",
"build_snapshot" : false,
"lucene_version" : "7.7.0",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
2,新建spring boot 项目。
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
application.properties文件配置:
##端口号
server.port=8888
##es地址
#节点名字,默认elasticsearch
spring.data.elasticsearch.cluster-name=elasticsearch
#节点地址,多个节点用逗号隔开
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300
#spring.data.elasticsearch.local=false
spring.data.elasticsearch.repositories.enable=true
新建实体类:
package org.lee.elasticsearch.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
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;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
@Document(indexName = "goods",type = "goods")
public class Goods implements Serializable {
@Id
private String id;
@Field
private String name;
@Field
private String description;
@Field(type = FieldType.Date)
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date createTime;
@Field(type = FieldType.Double)
private Double price;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
}
用到spring data封装的,继承ElasticsearchRepository接口,一些基本的里面都可以直接用。
package org.lee.elasticsearch.service;
import org.lee.elasticsearch.entity.Goods;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Component;
@Component
public interface GoodsRepository extends ElasticsearchRepository<Goods,String>{
}
controller测试:
package org.lee.elasticsearch.controller;
import com.alibaba.fastjson.JSON;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.lee.elasticsearch.config.GenUUID;
import org.lee.elasticsearch.entity.Goods;
import org.lee.elasticsearch.service.GoodsRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
@RestController
@RequestMapping("goods")
public class controller {
@Autowired
private GoodsRepository goodsRepository;
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
private static String INDEX_NAME = "goods";//goods_indo,goods_test
private static String TYPE_NAME = "goods";//doc,test
@RequestMapping("save")
public String save(){
System.out.println("save.....");
Goods goods = new Goods();
goods.setId(GenUUID.getUUID());
System.out.println("id====>"+goods.getId());
goods.setName("西瓜");
goods.setDescription("西瓜是夏天很好的解暑水果");
goodsRepository.save(goods);
return JSON.toJSONString(goods);
}
@RequestMapping("getById")
public String getById(){
System.out.println("查询方法。。。");
Iterable<Goods> list = goodsRepository.findAll();
return JSON.toJSONString(list);
}
@RequestMapping("getAll")
public String getAll(){
System.out.println("查询所有方法。。。");
Iterable<Goods> list = goodsRepository.findAll();
return JSON.toJSONString(list);
}
@RequestMapping("queryByPage")
public String queryByPage(Integer pageNum,Integer pageSize,String keywords){
System.out.println("pageNum:"+pageNum);
System.out.println("pageSize:"+pageSize);
System.out.println("keywords:"+keywords);
//构造排序器
FieldSortBuilder sortBuilder = SortBuilders.fieldSort("price");
sortBuilder.order(SortOrder.DESC);
//构造查询器
QueryBuilder queryBuilder = QueryBuilders.queryStringQuery(keywords);
//组合排序器,查询器等
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(matchAllQuery())
.withIndices("goods","goods_info","goods_test") //可以指定多个索引
.withTypes(TYPE_NAME,"doc","test") //可以指定多个type
.withQuery(queryBuilder)
.withSort(sortBuilder)
.withPageable(PageRequest.of(pageNum, pageSize))
.build();
List<Goods> list = elasticsearchTemplate.queryForList(searchQuery,Goods.class);
return JSON.toJSONString(list);
}
}
需要注意的是:GoodsRepository 继承了ElasticsearchRepository接口,里面提供了很丰富的一些基本的操作,可以自行去看源码,Elasticsearch最重要的就是search,有很强大的查询功能,查询也是最为复杂的。因此ElasticsearchRepository接口是spring framework 提供的并不能实现一些很复杂的查询功能。要想实现复杂的查询,就要用到Elasticsearch自己提供的ElasticsearchTemplate操作类,见上面的分页查询排序能功能,条件查询等。在这里只是一个简单的demo,仅供入门参考学习。