ElasticSearch使用

Java API操作ES

相关依赖:

xml 复制代码
<dependencies>
    <!-- ES的高阶的客户端API -->
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>7.6.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.11.1</version>
    </dependency>
    <!-- 阿里巴巴出品的一款将Java对象转换为JSON、将JSON转换为Java对象的库 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.62</version>
    </dependency>
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>6.14.3</version>
        <scope>test</scope>
    </dependency>
  
</dependencies>

使用JavaAPI来操作ES集群

初始化连接

使用的是RestHighLevelClient去连接ES集群,后续操作ES中的数据

java 复制代码
  private RestHighLevelClient restHighLevelClient;

    public JobFullTextServiceImpl() {
        // 建立与ES的连接
        // 1. 使用RestHighLevelClient构建客户端连接。
        // 2. 基于RestClient.builder方法来构建RestClientBuilder
        // 3. 用HttpHost来添加ES的节点
        RestClientBuilder restClientBuilder = RestClient.builder(
              new HttpHost("192.168.21.130", 9200, "http")
            , new HttpHost("192.168.21.131", 9200, "http")
            , new HttpHost("192.168.21.132", 9200, "http"));
        restHighLevelClient = new RestHighLevelClient(restClientBuilder);
    }

添加职位数据到ES中

  • 使用IndexRequest对象来描述请求
    • 可以设置请求的参数:设置ID、并设置传输ES的数据------注意因为ES都是使用JSON(DSL)来去操作数据的,所以需要使用一个FastJSON的库来将对象转换为JSON字符串进行操作
java 复制代码
@Override
public void add(JobDetail jobDetail) throws IOException {
    //1.	构建IndexRequest对象,用来描述ES发起请求的数据。
    IndexRequest indexRequest = new IndexRequest(JOB_IDX);

    //2.	设置文档ID。
    indexRequest.id(jobDetail.getId() + "");

    //3.	使用FastJSON将实体类对象转换为JSON。
    String json = JSONObject.toJSONString(jobDetail);

    //4.	使用IndexRequest.source方法设置文档数据,并设置请求的数据为JSON格式。
    indexRequest.source(json, XContentType.JSON);

    //5.	使用ES High level client调用index方法发起请求,将一个文档添加到索引中。
    restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
}

查询/删除/搜索/分页

复制代码
* 新增:IndexRequest
* 更新:UpdateRequest
* 删除:DeleteRequest
* 根据ID获取:GetRequest
* 关键字检索:SearchRequest
java 复制代码
@Override
public JobDetail findById(long id) throws IOException {
    // 1.	构建GetRequest请求。
    GetRequest getRequest = new GetRequest(JOB_IDX, id + "");

    // 2.	使用RestHighLevelClient.get发送GetRequest请求,并获取到ES服务器的响应。
    GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);

    // 3.	将ES响应的数据转换为JSON字符串
    String json = getResponse.getSourceAsString();

    // 4.	并使用FastJSON将JSON字符串转换为JobDetail类对象
    JobDetail jobDetail = JSONObject.parseObject(json, JobDetail.class);

    // 5.	记得:单独设置ID
    jobDetail.setId(id);

    return jobDetail;
}
java 复制代码
@Override
public void update(JobDetail jobDetail) throws IOException {
    // 1.	判断对应ID的文档是否存在
    // a)	构建GetRequest
    GetRequest getRequest = new GetRequest(JOB_IDX, jobDetail.getId() + "");

    // b)	执行client的exists方法,发起请求,判断是否存在
    boolean exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);

    if(exists) {
        // 2.	构建UpdateRequest请求
        UpdateRequest updateRequest = new UpdateRequest(JOB_IDX, jobDetail.getId() + "");

        // 3.	设置UpdateRequest的文档,并配置为JSON格式
        updateRequest.doc(JSONObject.toJSONString(jobDetail), XContentType.JSON);

        // 4.	执行client发起update请求
        restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
    }
}
java 复制代码
@Override
public void deleteById(long id) throws IOException {
    // 1.	构建delete请求
    DeleteRequest deleteRequest = new DeleteRequest(JOB_IDX, id + "");

    // 2.	使用RestHighLevelClient执行delete请求
    restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);

}
java 复制代码
@Override
public List<JobDetail> searchByKeywords(String keywords) throws IOException {
    // 1.构建SearchRequest检索请求
    // 专门用来进行全文检索、关键字检索的API
    SearchRequest searchRequest = new SearchRequest(JOB_IDX);

    // 2.创建一个SearchSourceBuilder专门用于构建查询条件
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

    // 3.使用QueryBuilders.multiMatchQuery构建一个查询条件(搜索title、jd),并配置到SearchSourceBuilder
    MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keywords, "title", "jd");

    // 将查询条件设置到查询请求构建器中
    searchSourceBuilder.query(multiMatchQueryBuilder);

    // 4.调用SearchRequest.source将查询条件设置到检索请求
    searchRequest.source(searchSourceBuilder);

    // 5.执行RestHighLevelClient.search发起请求
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    SearchHit[] hitArray = searchResponse.getHits().getHits();

    // 6.遍历结果
    ArrayList<JobDetail> jobDetailArrayList = new ArrayList<>();

    for (SearchHit documentFields : hitArray) {
        // 1)获取命中的结果
        String json = documentFields.getSourceAsString();

        // 2)将JSON字符串转换为对象
        JobDetail jobDetail = JSONObject.parseObject(json, JobDetail.class);

        // 3)使用SearchHit.getId设置文档ID
        jobDetail.setId(Long.parseLong(documentFields.getId()));

        jobDetailArrayList.add(jobDetail);
    }

    return jobDetailArrayList;
}
java 复制代码
@Override
public Map<String, Object> searchByPage(String keywords, int pageNum, int pageSize) throws IOException {
    // 1.构建SearchRequest检索请求
    // 专门用来进行全文检索、关键字检索的API
    SearchRequest searchRequest = new SearchRequest(JOB_IDX);

    // 2.创建一个SearchSourceBuilder专门用于构建查询条件
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

    // 3.使用QueryBuilders.multiMatchQuery构建一个查询条件(搜索title、jd),并配置到SearchSourceBuilder
    MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keywords, "title", "jd");

    // 将查询条件设置到查询请求构建器中
    searchSourceBuilder.query(multiMatchQueryBuilder);

    // 每页显示多少条
    searchSourceBuilder.size(pageSize);
    // 设置从第几条开始查询
    searchSourceBuilder.from((pageNum - 1) * pageSize);

    // 4.调用SearchRequest.source将查询条件设置到检索请求
    searchRequest.source(searchSourceBuilder);

    // 5.执行RestHighLevelClient.search发起请求
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    SearchHit[] hitArray = searchResponse.getHits().getHits();

    // 6.遍历结果
    ArrayList<JobDetail> jobDetailArrayList = new ArrayList<>();

    for (SearchHit documentFields : hitArray) {
        // 1)获取命中的结果
        String json = documentFields.getSourceAsString();

        // 2)将JSON字符串转换为对象
        JobDetail jobDetail = JSONObject.parseObject(json, JobDetail.class);

        // 3)使用SearchHit.getId设置文档ID
        jobDetail.setId(Long.parseLong(documentFields.getId()));

        jobDetailArrayList.add(jobDetail);
    }

    // 8.	将结果封装到Map结构中(带有分页信息)
    // a)	total -> 使用SearchHits.getTotalHits().value获取到所有的记录数
    // b)	content -> 当前分页中的数据
    long totalNum = searchResponse.getHits().getTotalHits().value;
    HashMap hashMap = new HashMap();
    hashMap.put("total", totalNum);
    hashMap.put("content", jobDetailArrayList);


    return hashMap;
}

使用scroll分页方式查询

  • 第一次查询,不带scroll_id,所以要设置scroll超时时间
  • 超时时间不要设置太短,否则会出现异常
  • 第二次查询,SearchSrollRequest
java 复制代码
@Override
public Map<String, Object> searchByScrollPage(String keywords, String scrollId, int pageSize) throws IOException {
    SearchResponse searchResponse = null;

    if(scrollId == null) {
        // 1.构建SearchRequest检索请求
        // 专门用来进行全文检索、关键字检索的API
        SearchRequest searchRequest = new SearchRequest(JOB_IDX);

        // 2.创建一个SearchSourceBuilder专门用于构建查询条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        // 3.使用QueryBuilders.multiMatchQuery构建一个查询条件(搜索title、jd),并配置到SearchSourceBuilder
        MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keywords, "title", "jd");

        // 将查询条件设置到查询请求构建器中
        searchSourceBuilder.query(multiMatchQueryBuilder);

        // 每页显示多少条
        searchSourceBuilder.size(pageSize);

        // 4.调用SearchRequest.source将查询条件设置到检索请求
        searchRequest.source(searchSourceBuilder);

        //--------------------------
        // 设置scroll查询
        //--------------------------
        searchRequest.scroll(TimeValue.timeValueMinutes(5));

        // 5.执行RestHighLevelClient.search发起请求
        searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

    }
    // 第二次查询的时候,直接通过scroll id查询数据
    else {
        SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId);
        searchScrollRequest.scroll(TimeValue.timeValueMinutes(5));

        // 使用RestHighLevelClient发送scroll请求
        searchResponse = restHighLevelClient.scroll(searchScrollRequest, RequestOptions.DEFAULT);
    }

    //--------------------------
    // 迭代ES响应的数据
    //--------------------------

    SearchHit[] hitArray = searchResponse.getHits().getHits();

    // 6.遍历结果
    ArrayList<JobDetail> jobDetailArrayList = new ArrayList<>();

    for (SearchHit documentFields : hitArray) {
        // 1)获取命中的结果
        String json = documentFields.getSourceAsString();

        // 2)将JSON字符串转换为对象
        JobDetail jobDetail = JSONObject.parseObject(json, JobDetail.class);

        // 3)使用SearchHit.getId设置文档ID
        jobDetail.setId(Long.parseLong(documentFields.getId()));

        jobDetailArrayList.add(jobDetail);
    }

    // 8.	将结果封装到Map结构中(带有分页信息)
    // a)	total -> 使用SearchHits.getTotalHits().value获取到所有的记录数
    // b)	content -> 当前分页中的数据
    long totalNum = searchResponse.getHits().getTotalHits().value;
    HashMap hashMap = new HashMap();
    hashMap.put("scroll_id", searchResponse.getScrollId());
    hashMap.put("content", jobDetailArrayList);

    return hashMap;
}

高亮查询

  1. 配置高亮选项
java 复制代码
// 设置高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("title");
highlightBuilder.field("jd");
highlightBuilder.preTags("<font color='red'>");
highlightBuilder.postTags("</font>");
  1. 需要将高亮的字段拼接在一起,设置到实体类中
java 复制代码
// 设置高亮的一些文本到实体类中
// 封装了高亮
Map<String, HighlightField> highlightFieldMap = documentFields.getHighlightFields();
HighlightField titleHL = highlightFieldMap.get("title");
HighlightField jdHL = highlightFieldMap.get("jd");

if(titleHL != null) {
 // 获取指定字段的高亮片段
 Text[] fragments = titleHL.getFragments();
 // 将这些高亮片段拼接成一个完整的高亮字段
 StringBuilder builder = new StringBuilder();
 for(Text text : fragments) {
     builder.append(text);
 }
 // 设置到实体类中
 jobDetail.setTitle(builder.toString());
}

if(jdHL != null) {
 // 获取指定字段的高亮片段
 Text[] fragments = jdHL.getFragments();
 // 将这些高亮片段拼接成一个完整的高亮字段
 StringBuilder builder = new StringBuilder();
 for(Text text : fragments) {
     builder.append(text);
 }
 // 设置到实体类中
 jobDetail.setJd(builder.toString());
}

ES与springboot相连

xml 复制代码
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
java 复制代码
@Document(indexName = "dahaiwuliang",type="book")
public class Book {

    private Integer id;
    private String name;
    private String author;
...
}
java 复制代码
public interface BookRepository extends ElasticsearchRepository<Book,Integer> {

    public List<Book> findBookByName(String name);
}
java 复制代码
	/**
     * SpringData ES索引
     */
    @Test
    public void test1(){
        Book book = new Book(1,"三国演义","罗贯中");
        bookRepository.index(book);
    }

    /**
     * 根据书名查询
     */
    @Test
    public void test2(){
        List<Book> list = bookRepository.findBookByName("演义");
        for (Book book:list) {
            System.out.println(book);
        }
    }
相关推荐
君不见,青丝成雪3 小时前
Flink双流join
大数据·数据仓库·flink
好好先森&4 小时前
Linux系统:C语言进程间通信信号(Signal)
大数据
EkihzniY4 小时前
结构化 OCR 技术:破解各类检测报告信息提取难题
大数据·ocr
吱吱企业安全通讯软件4 小时前
吱吱企业通讯软件保证内部通讯安全,搭建数字安全体系
大数据·网络·人工智能·安全·信息与通信·吱吱办公通讯
云手机掌柜4 小时前
Tumblr长文运营:亚矩阵云手机助力多账号轮询与关键词布局系统
大数据·服务器·tcp/ip·矩阵·流量运营·虚幻·云手机
rainFFrain6 小时前
Boost搜索引擎项目(详细思路版)
网络·c++·http·搜索引擎
Hello.Reader7 小时前
Elasticsearch Ruby 客户端安装与版本兼容指南
elasticsearch·jenkins·ruby
拓端研究室7 小时前
专题:2025全球消费趋势与中国市场洞察报告|附300+份报告PDF、原数据表汇总下载
大数据·信息可视化·pdf
阿里云大数据AI技术9 小时前
MaxCompute聚簇优化推荐功能发布,单日节省2PB Shuffle、7000+CU!
大数据