前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >elasticsearch搜索引擎的常用方法

elasticsearch搜索引擎的常用方法

作者头像
贫困的蚊子
发布2023-08-10 12:36:41
1770
发布2023-08-10 12:36:41
举报
文章被收录于专栏:贫困的蚊子贫困的蚊子

前言

本次使用的elasticsearch是7.x,与6.x相比,可以无需指定doc

准备

application.yml

配置连接地址,在spring下

代码语言:javascript
复制
spring:
  elasticsearch:
    rest:
      uris: http://47.92.173.115:92000
image-1681660394759
image-1681660394759

依赖

代码语言:javascript
复制
<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类

代码语言:javascript
复制
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,是个实体类,不是系统自带的

导入

代码语言:javascript
复制
@Autowired
    private RestHighLevelClient restHighLevelClient;

插入/添加

根据传来的实体类,进行添加

代码语言:javascript
复制
 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,进行搜索

代码语言:javascript
复制
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和要改成什么状态

代码语言:javascript
复制
 //修改/更新数据
    //这里要说下,根据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;
    }

多参数修改修改/更新

根据穿过来实体类,进行修改/更新

代码语言:javascript
复制
 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;
    }

条件分页

代码语言:javascript
复制
//条件分页
    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;

    }

统计总数

统计搜索引擎里面所有数量

代码语言:javascript
复制
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;
    }
}

条件统计

根据状态,统计总数

代码语言:javascript
复制
 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;
        }

    }

GPS定位

第一个:就是画圆,直线到达,看看距离够不够 第二个:一个正方形,根据2个点,画一个正方形,里面的数据全给拿出来 第三个:多个点,画图,图里面的数据全给你拿出来

image-1685777019993
image-1685777019993
image-1685777219692
image-1685777219692

代码: 这个代码晚上用的画圆,也就是第一个

代码语言:javascript
复制
@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();
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-04-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 准备
    • application.yml
      • 依赖
        • 工具类
        • 代码
          • 导入
            • 插入/添加
              • 条件搜索
                • 修改/更新数据
                  • 多参数修改修改/更新
                    • 条件分页
                      • 统计总数
                        • 条件统计
                          • GPS定位
                          相关产品与服务
                          Elasticsearch Service
                          腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档