本次使用的elasticsearch是7.x,与6.x相比,可以无需指定doc
配置连接地址,在spring下
spring:
elasticsearch:
rest:
uris: http://47.92.173.115:92000
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.7.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.7.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.7.1</version>
</dependency>
JsonUtil类
package com.yikekong.util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.io.IOException;
public class JsonUtil{
/**
* 反序列化
* @param json
* @param clazz
* @param <T>
* @return
* @throws IOException
*/
public static <T> T getByJson(String json, Class<T> clazz) throws IOException {
ObjectMapper mapper = new ObjectMapper();
// 在反序列化时忽略在 json 中存在但 Java 对象不存在的属性
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 在序列化时日期格式默认为 yyyy-MM-dd'T'HH:mm:ss.SSSZ
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//反序列化"2020-01-22T11:11:11"字符串为LocalDateTime格式的配置
mapper.registerModule(new JavaTimeModule());
return mapper.readValue(json, clazz);
}
/**
* 从json字符串中根据nodeName获取值
* @param nodeName
* @param json
* @return
* @throws IOException
*/
public static String getValueByNodeName(String nodeName, String json) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(json);
return jsonNode.findPath(nodeName).asText();
}
/**
* 序列化
* @param object
* @return
* @throws JsonProcessingException
*/
public static String serialize(Object object) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
// 在序列化时日期格式默认为 yyyy-MM-dd'T'HH:mm:ss.SSSZ
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//反序列化"2020-01-22T11:11:11"字符串为LocalDateTime格式的配置
mapper.registerModule(new JavaTimeModule());
return mapper.writeValueAsString(object);
}
}
形参是个DeviceDTO,是个实体类,不是系统自带的
@Autowired
private RestHighLevelClient restHighLevelClient;
根据传来的实体类,进行添加
public void createadd(DeviceDTO devicedt) throws Exception{
if(StringUtils.isEmpty(devicedt))
return;
if(devicedt.getDeviceId()==null)
return;
//设置那个库插入数据
IndexRequest indexRequest = new IndexRequest("devices");
//将传过来的数据转成json
String serialize = JsonUtil.serialize(devicedt);
//因为搜索引擎要的数据源是Map,所以将json转成Map
Map byJson = JsonUtil.getByJson(serialize, Map.class);
indexRequest.source(byJson);
indexRequest.id(devicedt.getDeviceId());
//将东西告诉es,启动插入/添加 可以理解启动搜索服务器
restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
System.out.println("添加ok");
}
根据传过来的id,进行搜索
public DeviceDTO deviceDTO(String deviceId) throws Exception{
//去那个库搜索
SearchRequest searchRequest = new SearchRequest("devices");
//设置搜索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//_id对应搜索引擎里面的,deviceId是形参
searchSourceBuilder.query(QueryBuilders.termQuery("_id",deviceId));
//将传入的id值,进行封装文档格式,准备告诉es
searchRequest.source(searchSourceBuilder);
//将东西告诉es,启动搜索 可以理解启动搜索服务器
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//获取结果中hits里面的内容,这里返回的数据有很多
//很多意思是,里面不只有我们需要的数据,还有一些其它参数
//所以下面不能直接判断它是不是空
SearchHits hits = search.getHits();
//获取数据几条,这就是为什么不能直接判断上面是不是空
long value = hits.getTotalHits().value;
if(value<=0){
return null;
}
DeviceDTO deviceDTO = null;
for (SearchHit hit : hits) {
//获取我们需要的数据,但返回是json格式
String sourceAsString = hit.getSourceAsString();
//转换到实体类对象
deviceDTO = JsonUtil.getByJson(sourceAsString,DeviceDTO.class);
break;
}
return deviceDTO;
}
传入要修改的id和要改成什么状态
//修改/更新数据
//这里要说下,根据id更新状态 我的状态是true和false
//如果更新成功返回true,失败就会报错,进入catch返回false
public boolean update(String deviceId,boolean status){
UpdateRequest updateRequest = new UpdateRequest("devices",deviceId).doc("status",status);
UpdateResponse update = null;
try {
update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
根据穿过来实体类,进行修改/更新
public boolean updateDeviceAlarm(DeviceDTO dto){
//双引号里面的搜索搜索引擎的
UpdateRequest updateRequest = new UpdateRequest("devices",dto.getDeviceId()).doc("alarm",dto.getAlarm(),"alarmName",dto.getAlarmName(),"level",dto.getLevel());
try {
restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
return false;
}
return true;
}
//条件分页
public Pager<DeviceDTO> page(Long pageIndex,Long pageSize, String deviceId, String tag, Integer state){
SearchRequest indexRequest = new SearchRequest("devices");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//多个查询条件使用
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//判断是否为空,返回值是boolen型
if(!Strings.isNullOrEmpty(deviceId)){
//QueryBuilders.wildcardQuery代表模糊查询方法
boolQueryBuilder.must(QueryBuilders.wildcardQuery("deviceId",deviceId+"*"));
}
if(!Strings.isNullOrEmpty(tag)){
boolQueryBuilder.must(QueryBuilders.wildcardQuery("tag","*"+tag+"*"));
}
//对于不确定的值,进行进一步判断
//状态(在线状态和告警状态) 0:在线 1:离线 2:一般告警 3:严重告警
if(state!=null){
//666
if(state.intValue()==0){
System.out.println("开始0");
System.out.println(state.intValue());
System.out.println(state);
System.out.println("结束0");
//QueryBuilders.termQuery代表精准查询方法
boolQueryBuilder.must(QueryBuilders.termQuery("online",true));
}else if (state.intValue() == 1){
boolQueryBuilder.must(QueryBuilders.termQuery("online",false));
}else if (state.intValue() == 2) {
boolQueryBuilder.must(QueryBuilders.termQuery("level",1));
}else if (state.intValue() == 3) {
boolQueryBuilder.must(QueryBuilders.termQuery("level",2));
}else {
boolQueryBuilder.must(QueryBuilders.termQuery("level",0));
}
}
//设置查询条件
searchSourceBuilder.query(boolQueryBuilder);
//设置第几页
searchSourceBuilder.from((pageIndex.intValue()-1)*pageSize.intValue());
//设置一页几条数据
searchSourceBuilder.size(pageSize.intValue());
//封装,准备告诉es
indexRequest.source(searchSourceBuilder);
try {
SearchResponse search = restHighLevelClient.search(indexRequest, RequestOptions.DEFAULT);
SearchHits hits = search.getHits();
long valu22e = hits.getTotalHits().value;
if(valu22e<=0){
return null;
}
List<DeviceDTO> li = new ArrayList<>();
for (SearchHit hit : hits) {
String sourceAsString = hit.getSourceAsString();
DeviceDTO byJson = JsonUtil.getByJson(sourceAsString, DeviceDTO.class);
li.add(byJson);
}
//设置分页对象
Pager<DeviceDTO> pager = new Pager<>(valu22e,pageSize);
//设置分页数据
pager.setItems(li);
return pager;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
统计搜索引擎里面所有数量
public Long getAllDeviceCount(){
CountRequest countRequest=new CountRequest("devices");
countRequest.query( QueryBuilders.matchAllQuery() );
try {
CountResponse response = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
return response.getCount();
} catch (IOException e) {
e.printStackTrace();
return 0L;
}
}
根据状态,统计总数
public Long getOfflineCount(boolean state){
CountRequest countRequest=new CountRequest("devices");
BoolQueryBuilder boolQueryBuilder=QueryBuilders.boolQuery();
//online是搜索引擎里面的
boolQueryBuilder.must( QueryBuilders.termQuery("online",state) );
//如需多个条件,复制上面一行,即可
countRequest.query( boolQueryBuilder );
try {
CountResponse response = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
return response.getCount();
} catch (IOException e) {
e.printStackTrace();
return 0L;
}
}
第一个:就是画圆,直线到达,看看距离够不够 第二个:一个正方形,根据2个点,画一个正方形,里面的数据全给拿出来 第三个:多个点,画图,图里面的数据全给你拿出来
代码: 这个代码晚上用的画圆,也就是第一个
@Override
public List<VmInfoDTO> search(VmSearch searchReq) {
//指定索引
SearchRequest searchRequest = new SearchRequest("vm");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//中心点及半径构建
GeoDistanceQueryBuilder geoDistanceQueryBuilder = new GeoDistanceQueryBuilder("location");
geoDistanceQueryBuilder.distance(searchReq.getDistance(), DistanceUnit.KILOMETERS);
geoDistanceQueryBuilder.point(searchReq.getLat(),searchReq.getLon());
//从近到远排序规则构建
GeoDistanceSortBuilder distanceSortBuilder = new GeoDistanceSortBuilder("location",searchReq.getLat(),searchReq.getLon());
distanceSortBuilder.unit(DistanceUnit.KILOMETERS);
distanceSortBuilder.order(SortOrder.ASC);
distanceSortBuilder.geoDistance(GeoDistance.ARC);
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
boolQueryBuilder.must(geoDistanceQueryBuilder);
searchSourceBuilder.query(boolQueryBuilder);
searchSourceBuilder.sort(distanceSortBuilder);
searchRequest.source(searchSourceBuilder);
try {
SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = searchResponse.getHits();
if(hits.getTotalHits().value <= 0){
return Lists.newArrayList();
}
List<VmInfoDTO> vmInfoList = Lists.newArrayList();
Arrays.stream(hits.getHits()).forEach(h->{
VmInfoDTO vmInfo = null;
try {
vmInfo = JsonUtil.getByJson(h.getSourceAsString(), VmInfoDTO.class);
//将千米转换为米
BigDecimal geoDis=new BigDecimal((double)h.getSortValues()[0]*1000);
vmInfo.setDistance(geoDis.intValue());
} catch (IOException e) {
log.error("convert vminfo error",e);
}
if(vmInfo!=null){
vmInfoList.add(vmInfo);
}
});
return vmInfoList;
} catch (IOException e) {
log.error("search location error",e);
return Lists.newArrayList();
}
}