java操作spring-data-elasticsearch开发流程
1、引入maven依赖
<!--elasticsearch-->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.4.3</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.4.3</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>transport-netty4-client</artifactId>
<version>6.4.3</version>
</dependency>
Spring Data Elasticsearch是Spring Data项目下的一个子模块,查看 Spring Data的官网:https://spring.io/projects/spring-data
springboot整合spring-data-elasticsearch引入下面的maven
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>3.2.3.RELEASE</version>
</dependency>
注意:
Spring Data Elasticsearch到目前为止暂时不支持elasticsearch7版本
下表显示了Spring Data Elasticsearch使用的Elasticsearch版本:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bsGrOsEy-1578361332485)(C:\Users\EDZ\AppData\Roaming\Typora\typora-user-images\image-20191226134011660.png)]
2、编写yml配置文件
server:
port: 9999
spring:
application:
name: springlog
spring:
data:
elasticsearch:
cluster-name: docker-cluster
cluster-nodes: 192.168.1.188:9300
repositories:
enabled: true
3、编写entity
Java可以通过编写实体类添加注解的方式创建索引
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.util.Date;
@Data
@Document(indexName = "logs",type = "log")
@NoArgsConstructor
@AllArgsConstructor
public class Log implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 编号
*/
@Id
private Long id;
/**
* 日志标题
*/
@Field(type = FieldType.Text,analyzer = "ik_max_word")
@NotBlank(message = "日志标题不能为空")
private String title;
/**
* 创建者
*/
@Field(type = FieldType.Text)
private String createBy;
/**
* 操作IP地址
*/
@Field(type = FieldType.Text)
private String remoteAddr;
/**
* 操作方式
*/
@Field(type = FieldType.Text)
private String method;
/**
* 执行时间
*/
@Field(type = FieldType.Date,format = DateFormat.custom,
pattern = "yyyy-MM-dd HH:mm:ss || yyyy-MM-dd || yyyy/MM/dd HH:mm:ss|| yyyy/MM/dd ||epoch_millis")
@JsonFormat (shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date time;
}
3.1 注解详解:
@Document:
代表一个文档记录
String indexName():索引名
String type() default “”:索引类型
boolean useServerConfiguration() default false:在创建索引时使用服务器端的设置,默认为false
short shards() default 5:分片数量,默认为5
short replicas() default 1:副本数量,默认为1
String refreshInterval() default “1s”:索引刷新的间隔时间,默认是1s
String indexStoreType() default “fs”:索引存储类型,默认是fs
boolean createIndex() default true:配置是否要创建repository引导的索引,默认是true
VersionType versionType() default VersionType.EXTERNAL:版本管理的配置,默认是VersionType.EXTERNAL
@Id:
用来将对象中id和ES中_id映射
@Field:
用来指定ES中的字段对应Mapping
type:
可以指定字段类型
映射类型: text , keyword , date ,integer, long , double , boolean or ip
analyzer:
用来指定使用哪种分词器
3.1.1 分词器
分词是指将文本转换成一系列单词(term or token)的过程,也可以叫做文本分析,在es里面成为Analysis
分词器是es中专门处理分词的组件,英文为Analyzer,它的组成如下:
-Character Filters
-针对原始文本进行处理,比如去除HTML标签、特殊标识符等
-Tokenizer
-将原始文本按照一定规则切分为单词
-Token Filters
-针对tokenizer处理的单词进行再加工,比如转小写、删除语气词、近义词和同义词等处理
3.1.2 ES自带分词器
分词器(Analyzer) | 特点 |
---|---|
Standard(es默认) | 支持多语言,按词切分并做小写处理 |
Simple | 按照非字母切分,小写处理 |
Whitespace | 按照空格来切分 |
Stop | 去除语气词,如the、an、的、这等 |
Keyword | 不分词 |
Pattern | 正则分词,默认\w+,即非字词符号做分隔符 |
Language | 常见语言的分词(30+) |
4、EsUtil
@Configuration
public class EsUtil {
@Bean
public RestHighLevelClient restHighLevelClient() {
//单个ip创建方式
HttpHost httpHost= new HttpHost("192.168.1.188", 9300);
Settings settings = Settings.builder()
.put("client.transport.sniff", false).build();
RestClientBuilder builder = RestClient.builder(httpHost);
RestHighLevelClient client = new RestHighLevelClient(builder);
return client;
//获取集群IP地址
/*String[] ipArr = host.split(",");
HttpHost[] httpHosts = new HttpHost[ipArr.length];
for (int i = 0; i < ipArr.length; i++) {
httpHosts[i] = new HttpHost(ipArr[i],port,scheme);
}
RestClientBuilder builder = RestClient.builder(httpHosts);
//获得HighLevelClient
RestHighLevelClient client = new RestHighLevelClient(builder);
return client;*/
}
/**
* 获取低水平客户端
* @return
*/
@Bean
public static RestClient restClient(RestHighLevelClient client) {
return client.getLowLevelClient();
}
/**
* 关闭连接
*/
public static void close(RestHighLevelClient client) {
if (client != null) {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
5、编写ESRepository
@Configuration
public interface ESRepository extends ElasticsearchRepository<Entity,类型> {
}
6、编写service
/**
* 多字段查询
* @param bgTime
* @param edTime
* @param serviceID
* @return
*/
public List<SysLoginLog> multiMatchQuery(Date bgTime, Date edTime, String serviceID){
List<SysLoginLog> logs = new ArrayList<>();
//搜索请求对象
SearchRequest searchRequest = new SearchRequest("syslogins");
//搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//搜索方式
//根据时间范围查询条件
QueryBuilder queryBuilder1 = QueryBuilders.rangeQuery("loginTime").from(bgTime).to(edTime);
//根据serviceID查询条件
QueryBuilder queryBuilder2 = QueryBuilders.multiMatchQuery("serviceId", serviceID);
//根据title查询条件
//整合查询条件
searchSourceBuilder.query(QueryBuilders.boolQuery()
.should(queryBuilder1)
.should(queryBuilder2));
searchRequest.source(searchSourceBuilder);
try {
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//搜索结果
SearchHits hits = searchResponse.getHits();
//得到匹配度高的文档
SearchHit[] searchHits = hits.getHits();
//日期格式化对象
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SysLoginLog log = new SysLoginLog();
for(SearchHit hit:searchHits){
//文档的主键
String id = hit.getId();
//源文档内容
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
long ID = (long) sourceAsMap.get("id");
String userName = (String)sourceAsMap.get("userName");
String loginName = (String) sourceAsMap.get("loginName");
String loginIp = (String) sourceAsMap.get("loginIp");
Date loginTime = (Date)sourceAsMap.get("loginTime");
String serviceId = (String) sourceAsMap.get("serviceId");
log.setId(ID);
log.setUserName(userName);
log.setLoginName(loginName);
log.setLoginIp(loginIp);
log.setLoginTime(loginTime);
log.setServiceId(serviceId);
logs.add(log);
}
return logs;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 分页
* @param str 查询条件
* @param currentPage 当前页
* @param size 页面大小
* @return
*/
public List<SysLoginLog> searchByPage(String str, Integer currentPage, Integer size){
if(currentPage==null){
currentPage = 1;
}
if(size==null){
size = 10;
}
Integer offset = (currentPage-1)*size;
System.out.println(offset+"---"+size);
if (StringUtils.isEmpty(str)){
Page<SysLoginLog> page = sysLoginRepository.findAll(PageRequest.of(offset, size));
System.out.println("查询条件是null呦!!!!!!!!!");
long count = page.getTotalElements();
//准备返回data
ArrayList<SysLoginLog> list = new ArrayList<>();
for (SysLoginLog log : page) {
SysLoginLog sysLoginLog = new SysLoginLog();
sysLoginLog.setId(log.getId());
sysLoginLog.setUserName(log.getUserName());
sysLoginLog.setLoginName(log.getLoginName());
sysLoginLog.setLoginIp(log.getLoginIp());
sysLoginLog.setLoginTime(log.getLoginTime());
sysLoginLog.setServiceId(log.getServiceId());
list.add(sysLoginLog);
}
return list;
}else {
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(queryStringQuery(str))
.withPageable(new PageRequest(offset, size))
.build();
Page<SysLoginLog> page = elasticsearchTemplate.queryForPage(searchQuery, SysLoginLog.class);
long count = page.getTotalElements();
//准备返回data
ArrayList<SysLoginLog> list = new ArrayList<>();
for (SysLoginLog log : page) {
SysLoginLog sysLoginLog = new SysLoginLog();
sysLoginLog.setId(log.getId());
sysLoginLog.setUserName(log.getUserName());
sysLoginLog.setLoginName(log.getLoginName());
sysLoginLog.setLoginIp(log.getLoginIp());
sysLoginLog.setLoginTime(log.getLoginTime());
sysLoginLog.setServiceId(log.getServiceId());
list.add(sysLoginLog);
}
return list;
}
}
7、编写controller
@RestController
@AllArgsConstructor
@RequestMapping("/log")
@Slf4j
@Api(tags = "登陆日志管理")
public class SysLoginController {
@Autowired
private SysLoginService sysLoginService;
/**
* 分页查询
* @param str
* @param currentPage
* @param size
* @return
*/
@GetMapping("/searchLoginPage")
@ApiOperation(value = "分页查询", notes = "日志器信息")
@ApiParam(name="日志模型,实体对象",value="日志模型,实体对象",required=true)
public R searchLoginPage(@RequestParam String str, @RequestParam Integer currentPage, @RequestParam Integer size){
return new R<>(sysLoginService.searchByPage(str, currentPage, size));
}
/**
* 多字段查询
* @param bgTime
* @param edTime
* @param serviceId
* @return
*/
@GetMapping("/multiMatchQueryLogin")
@ApiOperation(value = "多字段查询", notes = "日志器信息")
@ApiParam(name="日志模型,实体对象",value="日志模型,实体对象",required=true)
public R multiMatchQuery(@RequestParam@JsonFormat(shape = JsonFormat.Shape.STRING, pattern ="EEE MMM dd HH:mm:ss ZZZ yyyy")@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date bgTime,@RequestParam@JsonFormat(shape = JsonFormat.Shape.STRING, pattern ="EEE MMM dd HH:mm:ss ZZZ yyyy")@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date edTime,@RequestParam String serviceId){
return new R<>(sysLoginService.multiMatchQuery(bgTime,edTime,serviceId));
}
@InitBinder
public void initBinder(WebDataBinder binder, WebRequest request) {
//转换日期
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.UK);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
// CustomDateEditor为自定义日期编辑器
}
}
8、启动类
@EnableVinsuanResourceServer
@EnableVinsuanFeignClients
@SpringCloudApplication
@EnableResourceServer
//开启扫描搜索引擎的注解
@EnableElasticsearchRepositories(basePackages = "com.包.**")
@ComponentScan(basePackages = {"com.包.**"})
public class VinsuanLogApplication {
public static void main(String[] args) {
System.setProperty("es.set.netty.runtime.available.processors", "false");
SpringApplication.run(VinsuanLogApplication.class, args);
}
}