springboot操作elasticsearch

ElasticSearch

1、安装(Windows)?
首先准备几个包

elasticsearch-7.6.1-windows-x86_64
elasticsearch-analysis-ik-7.6.1
elasticsearch-head-master`在这里插入代码片`
kibana-7.6.1-windows-x86_64

2、环境安装?

需要安装node环境,启动head需要node环境。
通过cnpm install安装node_modules
cnpm run start启动即可启动head

3、解决跨域问题?

启动elasticsearch和head之后会发现head连接不上9200,需要解决跨域问题
在elasticsearch安装包中找到elasticsearch.yml中添加两行即可,如下:
http.cors.enabled: true
http.cors.allow-origin: "*"

4、安装kibana?

解压之后的kibana里面就有node_modules,直接启动bat即可。
首先进去是英文的,所以需要修改kibana.yml里面最后一行中的en改成zh-CN之后,重启即可。

5、IK分词器?

将ik分词器的解压包解压之后放进elasticsearch的plugins里面就可以了,可以自定义分词器,只需在config里面添加一个dic文件,然后在IKAnalyzer.cfg.xml中指定文件就行。

在这里插入图片描述
在这里插入图片描述
在IKAnalyzer.cfg.xml中的配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
	<comment>IK Analyzer 扩展配置</comment>
	<!--用户可以在这里配置自己的扩展字典 -->
	<entry key="ext_dict">wuheng.dic</entry>
	 <!--用户可以在这里配置自己的扩展停止词字典-->
	<entry key="ext_stopwords"></entry>
	<!--用户可以在这里配置远程扩展字典 -->
	<!-- <entry key="remote_ext_dict">words_location</entry> -->
	<!--用户可以在这里配置远程扩展停止词字典-->
	<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

常用的分词器

ik_smart:最粗粒度的拆分。
如:
    GET /_analyze
    {
        "analyzer": "ik_smart", 
        "text": "中华人民共和国人民大会堂"
    }

结果:
    {
      "tokens" : [
        {
          "token" : "中华人民共和国",
          "start_offset" : 0,
          "end_offset" : 7,
          "type" : "CN_WORD",
          "position" : 0
        },
        {
          "token" : "人民大会堂",
          "start_offset" : 7,
          "end_offset" : 12,
          "type" : "CN_WORD",
          "position" : 1
        }
      ]
    }

ik_max_word:最细粒度的拆分
如:
    GET /_analyze
    {
        "analyzer": "ik_max_word", 
        "text": "中华人民共和国人民大会堂"
    }

结果:
    {
  "tokens" : [
    {
      "token" : "中华人民共和国",
      "start_offset" : 0,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "中华人民",
      "start_offset" : 0,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "中华",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "华人",
      "start_offset" : 1,
      "end_offset" : 3,
      "type" : "CN_WORD",
      "position" : 3
    },
    {
      "token" : "人民共和国",
      "start_offset" : 2,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 4
    },
    {
      "token" : "人民",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 5
    },
    {
      "token" : "共和国",
      "start_offset" : 4,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 6
    },
    {
      "token" : "共和",
      "start_offset" : 4,
      "end_offset" : 6,
      "type" : "CN_WORD",
      "position" : 7
    },
    {
      "token" : "国人",
      "start_offset" : 6,
      "end_offset" : 8,
      "type" : "CN_WORD",
      "position" : 8
    },
    {
      "token" : "人民大会堂",
      "start_offset" : 7,
      "end_offset" : 12,
      "type" : "CN_WORD",
      "position" : 9
    },
    {
      "token" : "人民大会",
      "start_offset" : 7,
      "end_offset" : 11,
      "type" : "CN_WORD",
      "position" : 10
    },
    {
      "token" : "人民",
      "start_offset" : 7,
      "end_offset" : 9,
      "type" : "CN_WORD",
      "position" : 11
    },
    {
      "token" : "大会堂",
      "start_offset" : 9,
      "end_offset" : 12,
      "type" : "CN_WORD",
      "position" : 12
    },
    {
      "token" : "大会",
      "start_offset" : 9,
      "end_offset" : 11,
      "type" : "CN_WORD",
      "position" : 13
    },
    {
      "token" : "会堂",
      "start_offset" : 10,
      "end_offset" : 12,
      "type" : "CN_WORD",
      "position" : 14
    }
  ]
}

6、SpringBoot操作Elasticsearch

创建一个springboot项目,添加依赖

dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>

需要修改一下elasticsearch版本和安装的版本对应

<properties>
    <elasticsearch.version>7.6.1</elasticsearch.version>
</properties>

创建用户类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String filename;
    private String address;
    private Integer age;
}

编写配置类

@Configuration
public class ElasticSearchConfig {

    @Value("${elastic.hostname}")
    private String hostname;

    @Value("${elastic.port}")
    private String port;

    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient restHighLevelClient= new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost(hostname, Integer.parseInt(port),"http")));
        return restHighLevelClient;
    }

}

hostname和port为elasticsearch的地址和端口。

配置完成之后就可以进行操作了。

package com.wuheng.elasticsearch.elasticsearchtest;

import com.alibaba.fastjson.JSON;
import com.sun.org.apache.regexp.internal.RE;
import com.wuheng.elasticsearch.pojo.Other;
import com.wuheng.elasticsearch.pojo.User;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
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.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;

@RunWith(SpringRunner.class)
@SpringBootTest
@SuppressWarnings("all")
public class ElasticSearchTest01 {

    @Autowired
    @Qualifier("restHighLevelClient")
    private RestHighLevelClient client;

    /*

        解释:
        * 创建索引        CreateIndexRequest
        * 删除索引        DeleteIndexRequest
        * 查询是否存在索引  GetIndexRequest
        *
        * client.indices():用来操作index的,如get、create、delete
    *
    *
    * */

    //创建索引
    @Test
    public void CreateIndexRequest() throws IOException {
        CreateIndexRequest request = new CreateIndexRequest("wuheng");
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        System.out.println(response);
    }

    //查询索引是否存在
    @Test
    public void existRequest() throws IOException {
        GetIndexRequest request=new GetIndexRequest("wuheng");
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
    }
    
    //删除索引
    @Test
    public void DeleteIndexRequest() throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest("wuheng");
        AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
        System.out.println(response);
    }




    /*
    *
    * {
        "_index": "wuheng",
        "_type": "_doc",
        "_id": "5lb-y3kBS7iIP477fCur",
        "_version": 1,
        "_score": 1,
        "_source": {
            "address": "武汉",
            "age": 25,
            "filename": "吴恒"
            }
        }
    *
    * */

    //添加文档
    @Test
    public void addDocument() throws IOException {
        //创建连接请求
        IndexRequest request = new IndexRequest("wuheng");
        //创建对象
        User user = new User("吴恒", "武汉", 25);

        //可以设置,如果不设置就给一个默认值,如 5lb-y3kBS7iIP477fCur
        request.id("1");
        //请求超时不执行
        request.timeout("10s");

        //将对象转换成JSON格式数据放入请求中。即放入source中
        request.source(JSON.toJSONString(user), XContentType.JSON);
        //客户端传递请求
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        System.out.println(response.toString());
        System.out.println(response.status());
    }

    //修改文档
    @Test
    public void updateDocument() throws IOException {
        //获取索引为wuheng,id为1的文档
        UpdateRequest request=new UpdateRequest("wuheng","1");
        //请求超时不执行
        request.timeout("5s");

        //修改的信息
        User user=new User();
        user.setAge(29);
        user.setFilename("张三三");
        //将修改的信息放入请求,修改的时候调用doc();
        request.doc(JSON.toJSONString(user), XContentType.JSON);
        request.fetchSource(true);
        UpdateResponse update = client.update(request, RequestOptions.DEFAULT);
        System.out.println(update.toString());
        System.out.println(update.getIndex());
        System.out.println(update.getGetResult());
        System.out.println(update.status());
    }

    //删除文档
    @Test
    public void DeleteDocument() throws IOException {
        //删除索引为wuheng中id为1的文档(数据)
        DeleteRequest request=new DeleteRequest("wuheng","1");
        DeleteResponse delete = client.delete(request, RequestOptions.DEFAULT);
        System.out.println(delete.status());
        System.out.println(delete.toString());
    }

    //查询文档
    @Test
    public void SelectDocument() throws IOException {
        //查询索引为wuheng中id为1的文档(数据),存在则返回数据,不存在返回为null
        GetRequest request=new GetRequest("wuheng","5lb-y3kBS7iIP477fCur");
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        System.out.println(response.getSource());
    }

    //批量添加
    @Test
    public void BulkDocument() throws IOException {
        BulkRequest request = new BulkRequest("wuheng");
        request.timeout("10s");
        request.estimatedSizeInBytes();
         ArrayList<User> userList = new ArrayList<>();
        User user1=new User("张三","武汉",21);
        User user2=new User("李四","上海",28);
        User user3=new User("王五","天津",15);
        User user4=new User("赵六","内蒙古",5);
        User user5=new User("李七","武汉",45);
        Collections.addAll(userList,user1,user2,user3,user4,user5);
        userList.forEach((u)->request.add(new IndexRequest().source(JSON.toJSONString(u),XContentType.JSON)));
        BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
        System.out.println(response.status());

    }

    //搜索
    @Test
    public void SearchDocument() throws IOException {
        //创建搜锁索引为wuheng的请求
        SearchRequest request=new SearchRequest("wuheng");
        System.out.println("======================匹配所有=====================");
        allRequest(request);
        gethit(request);
        System.out.println("======================精确查询=====================");
        termRequest(request);
        gethit(request);
        System.out.println("======================范围查询=====================");
        fanweiRequest(request);
        gethit(request);
        System.out.println("======================多条件查询=====================");
        manyTiaoJianRequest(request);
        gethit(request);
        System.out.println("======================高亮=====================");
        HighSearch(request);
        gethit(request);


    }

    private void gethit(SearchRequest request) throws IOException {
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
        System.out.println(response);
    }

    private void termRequest(SearchRequest request){
        //条件构造器
        SearchSourceBuilder builder=new SearchSourceBuilder();
        TermQueryBuilder termQuery = QueryBuilders.termQuery("filename", "恒");
        builder.query(termQuery);
        request.source(builder);

    }

    private void allRequest(SearchRequest request) {
        //条件构造器
        SearchSourceBuilder builder=new SearchSourceBuilder();
        //匹配所有
        MatchAllQueryBuilder allQuery = QueryBuilders.matchAllQuery();
        builder.query(allQuery);
        //将查询条件放在请求中
        request.source(builder);
    }

    private void fanweiRequest(SearchRequest request){
        //条件构造器
        SearchSourceBuilder builder=new SearchSourceBuilder();
        RangeQueryBuilder rangeAge = QueryBuilders.rangeQuery("age").from(5).to(20);
        builder.query(rangeAge);
        request.source(builder);
    }

    /*
    * must:必须满足的条件
    * mustNot:必须不满足的条件
    * should:等同于or的作用
    * */
    private void manyTiaoJianRequest(SearchRequest request){
        SearchSourceBuilder builder = new SearchSourceBuilder();
        RangeQueryBuilder q1 = QueryBuilders.rangeQuery("age").from(5).to(20);
        TermQueryBuilder q2 = QueryBuilders.termQuery("address", "天");
        BoolQueryBuilder qb1 = QueryBuilders.boolQuery().must(q1).mustNot(q2);
        BoolQueryBuilder qb2 = QueryBuilders.boolQuery().must(q1).should(q2);
        BoolQueryBuilder qb3 = QueryBuilders.boolQuery().must(q1).must(q2);
        builder.query(qb1);
        builder.query(qb2);
        builder.query(qb3);
        request.source(builder);
    }

	//高亮
    public void HighSearch(SearchRequest request){
        SearchSourceBuilder builder=new SearchSourceBuilder();
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("filename", "张三");
        builder.query(matchQueryBuilder);
        //高亮的操作
        HighlightBuilder highlighter = new HighlightBuilder();
        //设置高亮字段
        highlighter.field("filename",1);
        //设置前缀
        highlighter.preTags("<em style='color:red>'");
        //设置后缀
        highlighter.postTags("</em>");
        builder.highlighter(highlighter);
        
        request.source(builder);
		 /*
		 返回的结果如下:
         {
            "took":2,
            "timed_out":false,
            "_shards":{
                "total":1,
                "successful":1,
                "skipped":0,
                "failed":0
            },
            "hits":{
                "total":{
                    "value":1,
                    "relation":"eq"
                },
                "max_score":2.7725885,
                "hits":[
                    {
                        "_index":"wuheng",
                        "_type":"_doc",
                        "_id":"J1asz3kBS7iIP477Zyye",
                        "_score":2.7725885,
                        "_source":{
                            "address":"武汉",
                            "age":21,
                            "filename":"张三"
                        },
                        "highlight":{
                            "filename":[
                                "<em style='color:red>'张</em><em style='color:red>'三</em>"
                            ]
                        }
                    }
                ]
            }
        }
        * */

		/*
			可以看到highlight中的filename已经加上了<em style="color:red"></em>的样式
		*/

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值