一 本地安装elasticsearch-7.6.2 + kibana-7.6.2 

  1.elasticsearch  本地启动

  2.elasticsearch  本地访问  http://localhost:9200/

  3.kibana 本地启动

  4.kibana  本地访问 http://localhost:5601/app/kibana#/home

二 Spring Boot整合ES(elasticsearch)+ 基础操作

1.Spring Boot 和 ES(elasticsearch) 对应版本关系

参考官网:

Spring Data Elasticsearch :: Spring Data Elasticsearch

   2. 在pom 引入相关jar包

        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.6.2</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.6.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-connector-elasticsearch6_2.11</artifactId>
            <version>1.9.2</version>
        </dependency>

  3.编写ES基本操作config

package com.example.xuxi2.config;

import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.params.HttpParams;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.ClearScrollRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.UpdateByQueryRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.io.IOException;

@Configuration
public class ElasticsearchConfig implements InitializingBean, DisposableBean {

    private final static Logger logger = LoggerFactory.getLogger(ElasticsearchConfig.class);


    @Resource
    private RestHighLevelClient restHighLevelClient;

    /**
     * ben 销毁时 关闭ES连接
     *
     * @throws Exception
     */
    @Override
    public void destroy() throws Exception {
        // 关闭Elasticsearch连接
        logger.info("...........................................关闭Elasticsearch连接.......");

        try {
            this.restHighLevelClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * bean 创建时 初始化 ES连接
     *
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        logger.info("............................................初始化Elasticsearch连接.......");
        restHighLevelClient = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http")));

    }


    /**
     * 批量创建文档
     * @param bulkRequest
     * @return
     * @throws IOException
     */
    public BulkResponse  bulk(BulkRequest bulkRequest) throws IOException{
        BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        return bulk;

    }

    /**
     * scroll 滚动查询
     * @param scrollRequest
     * @return
     * @throws IOException
     */
    public SearchResponse  scroll(SearchScrollRequest  scrollRequest)throws  IOException{
        SearchResponse scroll = restHighLevelClient.scroll(scrollRequest, RequestOptions.DEFAULT);
         return scroll;

    }


    /**
     * 关闭Scroll链接
     */
    public void clearScroll(String scrollId) throws IOException {
        // 清除 Scroll 连接
        ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
        clearScrollRequest.addScrollId(scrollId);

            restHighLevelClient.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);

    }

    /**
     * 保存
     *
     * @param indexRequest
     * @throws IOException
     */

    public IndexResponse save(IndexRequest indexRequest) throws IOException {
        IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        return index;
    }

    /**
     * 查询
     *
     * @param request
     * @throws IOException
     */
    public SearchResponse query(SearchRequest request) throws IOException {
        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        return search;
    }


    /**
     * 判断是否存在
     *
     * @param getRequest
     * @return
     * @throws IOException
     */
    public Boolean exists(GetRequest getRequest) throws IOException {
        boolean exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
        return exists;
    }


    /**
     * 修改
     *
     * @param updateRequest
     * @return
     * @throws IOException
     */
    public UpdateResponse update(UpdateRequest updateRequest) throws IOException {
        UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
        return update;
    }


    /**
     * 修改
     *
     * @param updateRequest
     * @return
     * @throws IOException
     */
    public BulkByScrollResponse updateQuery(UpdateByQueryRequest updateRequest) throws IOException {
        BulkByScrollResponse update = restHighLevelClient.updateByQuery(updateRequest, RequestOptions.DEFAULT);
        return update;
    }

    /**
     * 删除
     *
     * @param deleteRequest
     * @return
     * @throws IOException
     */
    public DeleteResponse dal(DeleteRequest deleteRequest) throws IOException {
        DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        return delete;
    }

}

  三.ES基本操作  java 实现

         1.查询(精确,范围,in 模糊) 
    public void query() {
        try {
            SearchRequest request = new SearchRequest(INDICESLIST);
            SearchSourceBuilder builder = new SearchSourceBuilder();

            //多个条件 构建SearchSourceBuilder 查询参数 构建一个精确匹配查询,即查找指定字段(field)等于指定值(value)的文档。
            //builder.query(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("user","张三12")).must(QueryBuilders.termQuery("name","java 实现23更新")));

            //rangeQuery(String field): 构建一个范围查询,可以指定字段的值在一个范围内   gt 大于 gte 大于等于 lt 小于 lte 小于等于
            // builder.query(QueryBuilders.boolQuery().must(QueryBuilders.rangeQuery("age").gt("40").lt("50")));

            //前缀模糊匹配  对应mysql 中的 %
            //  builder.query(QueryBuilders.matchPhrasePrefixQuery("user","张858"));

            //多个值查询  对应mysql 中的in
         //   builder.query(QueryBuilders.termsQuery("age", queryInt));
            //默认从0开始
            builder.from(0);
            //分页的大小,默认为10,当查询数量超过1万的时候 会进行深分页
            builder.size(23);

            request.source(builder);
            SearchResponse query = elasticsearchConfig.query(request);
            for (SearchHit hit : query.getHits().getHits()) {
                logger.info("查询ES 结果{}", JSONObject.toJSONString(hit.getSourceAsMap()));
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
     2.分页的情况(在ES查询的时候 size 的值大于1W的时候就会出现异常,这个时候就会用的scroll进行深分页)
大于1W数据的查询结果

大于1W数据的查询-优化
 public void pageQuery() {
        try {
            List<UserVo> list = new ArrayList<>();
            SearchResponse searchResponse = null;
            SearchRequest request = new SearchRequest(INDICESLIST);
            SearchSourceBuilder builder = new SearchSourceBuilder();
            //默认从0开始
            builder.from(0);
            //分页的大小,默认为10,当查询数量超过1万的时候 会进行深分页
            builder.size(1000);
            request.source(builder);

            // 设置滚动查询过期时间 5分钟
            Scroll scroll = new Scroll(TimeValue.timeValueMinutes(5));
            request.scroll(scroll);

            searchResponse = elasticsearchConfig.query(request);
            logger.info("查询ES 条数为 = " + searchResponse.getHits().getHits().length);

            //放入第一批数据
            if (searchResponseIsNotNull(searchResponse)) {
                this.buildResponse(searchResponse, list);
            }

            // scrollId循环获取结果
            while (searchResponseIsNotNull(searchResponse)) {
                // 设置滚动查询参数
                SearchScrollRequest scrollRequest = new SearchScrollRequest(searchResponse.getScrollId());
                scrollRequest.scroll(scroll);
                // 通过ScrollId进行滚动查询
                searchResponse = elasticsearchConfig.scroll(scrollRequest);
                //放入往后批次的数据
                this.buildResponse(searchResponse, list);
            }
            elasticsearchConfig.clearScroll(searchResponse.getScrollId());
            logger.info("ES scroll 查询数据结果 ==" + list.size());

        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 处理信息
     */
    private List<UserVo> buildResponse(SearchResponse searchResponse, List<UserVo> list) {
        if (searchResponseIsNotNull(searchResponse)) {
            SearchHit[] hits = searchResponse.getHits().getHits();
            // 实体转换
            List<UserVo> collect = Arrays.stream(hits)
                    .map(hit -> JSON.parseObject(hit.getSourceRef().utf8ToString(), UserVo.class))
                    .collect(Collectors.toList());
            list.addAll(collect);
        }
        return null;
    }


    /**
     * 判断返回内容是否为空
     */
    private boolean searchResponseIsNotNull(SearchResponse searchResponse) {
        return !Objects.isNull(searchResponse)
                && !Objects.isNull(searchResponse.getHits())
                && !Objects.isNull(searchResponse.getHits().getHits())
                && searchResponse.getHits().getHits().length > 0;
    }
3.修改

   java 实现

 public void update() {
        try {
            Map<String, Object> alMap = Maps.newHashMap();
            alMap.put("user", "java 实现更新");
            alMap.put("message", "java 实现更新");
            User user = new User();
            user.setName("java 实现更新");
            user.setMessage("java 实现更新");
            UpdateRequest updateRequest = new UpdateRequest();
            //指定索引name、type和id
            updateRequest.index(INDICES).id("02g9_owBJ5blg2GrL6qG");
            //指定更新的字段,map格式
            // updateRequest.doc(alMap);
            //或者指定更新的字段,json格式传递,同局部更新代码V1版,加上XContentType.JSON即可
            updateRequest.doc(JSON.toJSONString(user), XContentType.JSON);
            //如果要更新的文档在更新操作的get和索引阶段之间被另一个操作更改,那么要重试多少次更新操作
            updateRequest.retryOnConflict(3);
            updateRequest.fetchSource(true);
            UpdateResponse update = elasticsearchConfig.update(updateRequest);
            logger.info("修改返回状态= ", update.status());

            SearchRequest searchRequest = new SearchRequest(INDICES);
            SearchSourceBuilder builder9 = new SearchSourceBuilder();
            builder9.query(QueryBuilders.matchQuery("id", "1848bf28-34a8-4c16-bd0e-a6b5b850d369"));
            searchRequest.source(builder9);
            SearchResponse query1 = elasticsearchConfig.query(searchRequest);
            for (SearchHit hit : query1.getHits().getHits()) {
                logger.info("修改后结果为 {} ", JSONObject.toJSONString(hit.getSourceAsMap()));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

执行结果 

ES查询结果

 3.删除,这里时根据es生成的id 进行删除

 public void dal() {
        try {
            DeleteRequest deleteRequest = new DeleteRequest(INDICES, "UIn144wBvDNhEK-gn-YT");
            DeleteResponse dal = elasticsearchConfig.dal(deleteRequest);
            logger.info("删除结果 = ", dal.status());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
 4.ES 基本查询语法

#查询
GET /kibana_query_index/_search?q=name:京


#单字段查询,查询语句中开始和结束中不能有注释 否则会有问题
GET kibana_query_index/_search
{
  "query": {
    "match": {
      "name": "北京"
    
  }
}
 

#查询,展示特定的字段信息
GET kibana_query_index/_search
{
  "query": {
    "match": {
      "name": "北京"
    }
  },
  "_source": ["name","desc"]
}


#查询 排序  分页(from 页码  size 每页的条数)

GET kibana_query_index/_search
{
  "query": {
    "match": {
      "name": "北京"
    }
  },
  "sort": [
    {
      "age": {
        "order": "asc"
      }
    }
  ],
  "from": 0,
  "size": 12
}


#多条件bool 值查询 ,must 命令 查询条件都要满足 并的关系,相当于mysql 中的and 
GET kibana_query_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
           "name": "北京"
          }
        },
        {
          "match": {
            "age":12
          }
        }
      ]
    }
  }
}

#多条件bool 值查询 ,should 命令 查询条件满足一个即可,相当于mysql 中的or 
GET kibana_query_index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
           "name": "北京"
          }
        },
        {
          "match": {
            "age":12
          }
        }
      ]
    }
  }
}

# must_not 不等于查询条件的数据
GET kibana_query_index/_search
{
  "query": {
    "bool": {
      "must_not": [ 
        {
          "match": {
            "age":12
          }
        }
      ]
    }
  }
}


#范围查询 gt 大于 gte 大于等于 lt 小于 lte 小于等于
GET kibana_query_index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
           "name": "北京"
          }
        } 
      ], 
      "filter": [
        {"range": {
          "age": {
            "gte": 1,
            "lte": 90
          }
        }}
      ]
    }
  }
}


#单字段查询 文档 关键字查询,多个条件使用空格隔开,只要满足其中一个结果就可以被查出,这个时候可以通过分值进行基本判断
GET kibana_query_index/_search
{
  "query": {
    "match": {
      "tags": "儿 门"
    }
  }
}


#创建索引库
PUT testdb
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "desc": {
        "type": "keyword"
      }
    }
  }
}
#插入数据1
PUT testdb/_doc/1
{
  "name": "李四在学java name",
  "desc": "李四在学java desc"
}

#插入数据2
PUT testdb/_doc/2
{
  "name": "李四在学java name2",
  "desc": "李四在学java desc2"
}


#查询  keyword 字段类型不会被分词器解析  没有被分析

GET _analyze
{
  "analyzer": "keyword",
  "text": "李四在学java name"
}

#查询  standard字段类型会被分词器解析 拆分后的数据 被分析了

GET _analyze
{
  "analyzer": "standard",
  "text": "李四在学java name"
}


GET testdb/_search
{
  "query": {
    "term": {
       
        "name": "李"
       
    }
  }
}

GET testdb/_search
{
  "query": {
    "term": {
       
        "desc": "李四在学java desc2"
       
    }
  }
}


#高亮显示highlight 默认 em 标签
 
GET kibana_query_index/_search
{
  "query": {
    "match": {
      "name": "北京"
    }
  },
  "highlight": {
    "fields": {
      "name": {}
    }
  }
}



#高亮显示highlight  自定义标签 pre_tags 标签前缀  post_tags  标签后缀
GET kibana_query_index/_search
{
  "query": {
    "match": {
      "name": "北京"
    }
  },
  "highlight": {
    "pre_tags": "<p sdfsdf>", 
    "post_tags": "</p>", 
    "fields": {
      "name": {}
    }
  }
}

更多推荐