ElasticSearch的详细使用


typora-copy-images-to: images


ElasticSearch

1、ElasticSearch 安装及可视化(Windows)

安装:ElasticSearch、head可视化、Kibana、IK

  • 1、下载 es: https://www.elastic.co/cn/downloads/elasticsearch

  • 2、启动 esbin 目录下的 elasticsearch.bat 文件

  • 3、下载安装可视化界面 ElasticSearch head插件: https://github.com/mobz/elasticsearch-head

  • 4、启动 head 插件:进入 head 目录进入 cmd 命令

    npm install (快点的话用 cnpm install,此步骤只在安装时使用,已安装则不必运行)
    npm run start (启动)
    在浏览器中打开: http://localhost:9100/

  • 5、连接测试发现,存在跨域问题:配置 es 中的 yml 文件后面加上

    http.cors.enabled: true
    http.cors.allow-origin: “*”

  • 6、重启 es

  • 7、下载 Kibana (版本与 es 对应): https://www.elastic.co/cn/downloads/kibana

  • 8、启动 Kibanabin 目录下的 kibana.bat 文件,并在浏览器上访问:http://localhost:5601

    在这里插入图片描述

  • 9、将 Kibana 界面汉化(选择性修改):在 config 目录下 kibana.yml 文件后面加上

    i18n.locale: “zh-CN”

  • 10、重启 Kibana

  • 11、下载 IK (版本跟 es 对应): https://github.com/medcl/elasticsearch-analysis-ik **

  • 12、将 IK 放入到 es 文件下的 plugins 目录下的 IK 文件夹中(IK 文件夹自己创建)

  • 13、重启 es,head 插件,Kibana




2、启动 ElasticSearch

  • 运行安装步骤中的:2、4、8



3、IK 分词器

ik_smart

  • 最小切分

  • 将“非常喜欢樊召康最小切分

    发送请求:

    GET _analyze
    {
    “analyzer”: “ik_smart”,
    “text”: “非常喜欢樊召康”
    }

    返回json数据

    {
      "tokens" : [
        {
          "token" : "非常",
          "start_offset" : 0,
          "end_offset" : 2,
          "type" : "CN_WORD",
          "position" : 0
        },
        {
          "token" : "喜欢",
          "start_offset" : 2,
          "end_offset" : 4,
          "type" : "CN_WORD",
          "position" : 1
        },
        {
          "token" : "樊",
          "start_offset" : 4,
          "end_offset" : 5,
          "type" : "CN_CHAR",
          "position" : 2
        },
        {
          "token" : "召",
          "start_offset" : 5,
          "end_offset" : 6,
          "type" : "CN_CHAR",
          "position" : 3
        },
        {
          "token" : "康",
          "start_offset" : 6,
          "end_offset" : 7,
          "type" : "CN_CHAR",
          "position" : 4
        }
      ]
    }
    


ik_max_word

  • 最细粒度划分

  • 将“非常喜欢樊召康最细粒度划分

    发送请求:

    GET _analyze
    {
    “analyzer”: “ik_max_word”,
    “text”: “非常喜欢樊召康”
    }

    返回json数据:

    {
      "tokens" : [
        {
          "token" : "非常",
          "start_offset" : 0,
          "end_offset" : 2,
          "type" : "CN_WORD",
          "position" : 0
        },
        {
          "token" : "喜欢",
          "start_offset" : 2,
          "end_offset" : 4,
          "type" : "CN_WORD",
          "position" : 1
        },
        {
          "token" : "樊",
          "start_offset" : 4,
          "end_offset" : 5,
          "type" : "CN_CHAR",
          "position" : 2
        },
        {
          "token" : "召",
          "start_offset" : 5,
          "end_offset" : 6,
          "type" : "CN_CHAR",
          "position" : 3
        },
        {
          "token" : "康",
          "start_offset" : 6,
          "end_offset" : 7,
          "type" : "CN_CHAR",
          "position" : 4
        }
      ]
    }
    


添加分词器

  • 发现问题:上面的“樊召康”被拆分了,不希望被拆分

  • 解决问题:自己需要的词,需要自己添加到我们的分词器的字典中

  • 步骤(两步)

    • 第一步:在 IK 文件下的 config 目录下创建 .dic 文件

      • 例如:创建 fzk.dic 文件,内容为 樊召康
    • 第二步:重启 ElasticSearch、Kibana

    • 第三步:在 Kibana 网址中进行请求

      发送请求:

      GET _analyze
      {
      “analyzer”: “ik_smart”,
      “text”: “非常喜欢樊召康”
      }

      返回json数据:樊召康未被拆分

      {
        "tokens" : [
          {
            "token" : "非常",
            "start_offset" : 0,
            "end_offset" : 2,
            "type" : "CN_WORD",
            "position" : 0
          },
          {
            "token" : "喜欢",
            "start_offset" : 2,
            "end_offset" : 4,
            "type" : "CN_WORD",
            "position" : 1
          },
          {
            "token" : "樊召康",
            "start_offset" : 4,
            "end_offset" : 7,
            "type" : "CN_WORD",
            "position" : 2
          }
        ]
      }
      



4、简单语句使用

增加(PUT)

PUT /fzk/type/1
{
  "name": "樊召康123",
  "age": 20
}

//PUT: 请求头
//fzk: 索引名称
//type: 类型名称
//1: 特定的ID
//{}: json数据,存储的信息


修改(POST)

POST /fzk/type/1/_update
{
  "doc": {
    "name": "fzk"
  }
}

//POST: 请求头
//fzk: 索引名称
//type: 类型名称
//1: 修改的这个ID的数据
//{}: json数据,存储的信息,修改 “name” 为 “fzk”


删除(DELETE)

DELETE /fzk

//DELETE: 请求头
//fzk: 索引名称
//删除索引为 “fzk”


查询(GET)

初始数据

{
    "_index" : "index1",
    "_type" : "type1",
    "_id" : "1",
    "_score" : 1.0,
    "_source" : {
        "name" : "樊召康123",
        "age" : 20
    }
},
{
    "_index" : "index1",
    "_type" : "type1",
    "_id" : "2",
    "_score" : 1.0,
    "_source" : {
        "name" : "222",
        "age" : 10
    }
},
{
    "_index" : "index1",
    "_type" : "type1",
    "_id" : "4",
    "_score" : 1.0,
    "_source" : {
        "name" : "樊召康1739084",
        "age" : 15
    }
},
{
    "_index" : "index1",
    "_type" : "type1",
    "_id" : "3",
    "_score" : 1.0,
    "_source" : {
        "name" : "1732047190樊召康1739084",
        "age" : 40
    }
}


简单查询

  • _source:输出特定的字段数据
  • sort:排序
  • from-size:分页
GET /index1/type1/_search
{
  "query": {
    "match": {
      "name": "樊召康"
    }
  }
}
//GET: 请求头
//index1: 索引名称
//type1: 类型名称
//_search: 所有数据
//{}: json数据,查询条件
//query: 查询
//match: 相似匹配,查询 “name” 中含有 “樊召康” 的所有数据,相当于SQL中的:like %樊召康%



GET /index1/type1/_search
{
  "query": {
    "match": {
      "name": "樊召康"
    }
  },
  "_source": ["name"]
}
//_source: 输出只有 “name” 字段的数据,相当于SQL中的:select name




GET /index1/type1/_search
{
  "query": {
    "match": {
      "name": "樊召康"
    }
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ]
}
//sort: 排序,按照 “age” 字段进行降序,相当于SQL中的:order by age desc




GET /index1/type1/_search
{
  "query": {
    "match": {
      "name": "樊召康"
    }
  },
  "from": 0,
  "size": 10
}
//from: 第 0 条数据开始
//size: 第 0+10 条数据结束
//相当于MySQL中的:limit m, n


复杂查询(bool查询)

  • must:与(&&)
  • must_not:非(!)
  • should:或(||)
  • filter:过滤器
GET /index1/type1/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "樊召康"
          }
        },
        {
          "match": {
            "age": 20
          }
        }
      ]
    }
  }
}
//must: 与 条件(&&),相当于SQL中的:and
//查询 “name” 字段中含有 “樊召康” 且 “age” 为 20 的所有数据




GET /index1/type1/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "match": {
            "name": "樊召康"
          }
        }
      ]
    }
  }
}
//must_not: 非(!),相当于SQL中的:not
//查询 “name” 字段中不含有 “樊召康” 的所有数据




GET /index1/type1/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": "樊召康"
          }
        },
        {
          "match": {
            "age": 20
          }
        }
      ]
    }
  }
}
//should: 或(||),相当于SQL中的:or
//查询 “name” 字段中含有 “樊召康” 或 “age” 为 20 的所有数据




GET /index1/type1/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "樊召康"
          }
        }
      ],
      "filter": {
        "range": {
          "age": {
            "gte": 10,
            "lte": 20
          }
        }
      }
    }
  }
}
//filter: 过滤器
//range: 返回匹配,相当于SQL中的:>, >=, <, <=
//>:gt, >=:gte, <:lt, <=:lte
//查询 “name” 字段中含有 “樊召康” 且 “age” 为 10<=age<=20 的所有数据


匹配多个条件

GET /index1/type1/_search
{
  "query": {
    "match": {
      "name": "樊 康"
    }
  }
}
//在一个字段中查询多个条件,只需用 “空格” 将条件隔开,es 会根据权重来进行排序
//例如上面的: "name": "樊 康"  ,  查询 “name” 中包含 “樊”,“康” 的数据根据权重进行排序


精确查询

  • term:直接根据倒排索引指定的词条进行精确的查找
GET /index1/type1/_search
{
  "query": {
    "term": {
      "name": "樊召康123"
    }
  }
}
//term: 精确匹配,相当于SQL中的:=
//查询 “name” 大于 “樊召康123” 的所有数据


高亮查询

  • highlight:高亮
GET /index1/type1/_search
{
  "query": {
    "match": {
      "name": "樊召康"
    }
  },
  "highlight": {
    "fields": {
      "name": {}
    }
  }
}
//highlight: 高亮
//fields: 高亮的数据,"name": {} 代表:将查到的 “樊召康” 三个字高亮 
//返回值高亮的部分:"<em>樊</em><em>召</em><em>康</em>123"




GET /index1/type1/_search
{
  "query": {
    "match": {
      "name": "樊召康"
    }
  },
  "highlight": {
    "pre_tags": "<p style='color:red'>",
    "post_tags": "</p>", 
    "fields": {
      "name": {}
    }
  }
}
//自定义高亮的属性
//pre_tags: 前缀标签
//post_tags: 后缀标签
//返回值高亮的部分:"<p style='color:red'>樊</p><p style='color:red'>召</p><p style='color:red'>康</p>123"



5、集成 SpringBoot

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/java-rest-high.html

环境搭建(两步)

  • 第一步:创建SpringBoot工程,并在 pom.xml 文件中引入依赖

    特别注意:引入的包的版本要与安装的 es 版本相同(我安装的是 7.6.1,以7.6.1为例)

    <!-- 将修改版本 -->
    <properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.6.1</elasticsearch.version>
    </properties>
    
    <!-- 引入依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
    
  • 第二步:编写配置文件

    @Configuration
    public class ElasticSearchClientConfig {
        /**
         * 单机配置
         */
        @Bean
        public RestHighLevelClient restHighLevelClient() {
            RestHighLevelClient client = new RestHighLevelClient(
                    RestClient.builder(
                            new HttpHost("localhost", 9200, "http")));
            return client;
        }
    
        /**
         * 集群配置
         */
        /*
        @Bean
        public RestHighLevelClient restHighLevelClient() {
            RestHighLevelClient client = new RestHighLevelClient(
                    RestClient.builder(
                            //集群配置
                            new HttpHost("localhost", 9200, "http"),
                            new HttpHost("localhost", 9201, "http")));
            return client;
        }
         */
    }
    



索引 API 的简单使用

  • 创建索引、判断索引是否存在、删除索引

    @RunWith(SpringRunner.class)
    @SpringBootTest
    class SpringbootinitializrApplicationTests {
        
        @Autowired
        @Qualifier("restHighLevelClient")
        private RestHighLevelClient client;
    
       /**
         * 创建索引
         * 参考地址:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/java-rest-high-create-index.html
         */
        @Test
        public void createIndex() throws IOException {
            //创建索引请求
            CreateIndexRequest request = new CreateIndexRequest("fzk");
            //创建索引
            CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
            System.out.println(response);
        }
    
    
        /**
         * 索引是否存在
         * 参考地址:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/java-rest-high-indices-exists.html
         */
        @Test
        public void isIndexExists() throws IOException {
            //创建获取索引请求
            GetIndexRequest request = new GetIndexRequest("fzk");
            //判断是否存在索引
            boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
            System.out.println(exists);
        }
    
    
        /**
         * 删除索引
         * 参考地址:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/java-rest-high-delete-index.html
         */
        @Test
        public void deleteIndex() throws IOException {
            //获取删除索引请求
            DeleteIndexRequest request = new DeleteIndexRequest("fzk");
            //删除索引
            AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
            System.out.println(delete.isAcknowledged());
        }
    }
    



文档 API 的简单使用

  • 实体类

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Person {
        private String name;
        private int age;
    }
    
  • 增删改查文档

    @RunWith(SpringRunner.class)
    @SpringBootTest
    class SpringbootinitializrApplicationTests {
        
        @Autowired
        @Qualifier("restHighLevelClient")
        private RestHighLevelClient client;
    
       /**
         * 给索引添加数据
         * 参考地址:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/java-rest-high-document-index.html
         */
        @Test
        public void addData() throws IOException {
            //创建对象
            Person person = new Person("樊召", 10);
            //创建索引请求
            IndexRequest request = new IndexRequest("fzk");
            //设置索引特定的 id 值
            request.id("1");
            //设置内容
            request.source(JSON.toJSONString(person), XContentType.JSON);
            //超时时间
            request.timeout("1s");
            //请求-响应
            IndexResponse response = client.index(request, RequestOptions.DEFAULT);
            System.out.println(response.toString());
            System.out.println(response.status());
        }
    
    
        /**
         * 判断文档是否存在
         * 参考地址:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/java-rest-high-document-exists.html
         */
        @Test
        public void isDataExists() throws IOException {
            //创建索引请求
            GetRequest getRequest = new GetRequest("fzk", "1");
            //不获取 _source 中的数据
            getRequest.fetchSourceContext(new FetchSourceContext(false));
            getRequest.storedFields("_none_");
            //判断是否存在
            boolean exists = client.exists(getRequest, RequestOptions.DEFAULT);
            System.out.println(exists);
        }
    
    
        /**
         * 获取文档内容
         * 参考地址:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/java-rest-high-document-get.html
         */
        @Test
        public void getData() throws IOException {
            GetRequest getRequest = new GetRequest("fzk", "1");
            //获取文档内容
            GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
            System.out.println(getResponse.getSource());
            System.out.println(getResponse);
        }
    
    
        /**
         * 修改文档内容
         * 参考地址:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/java-rest-high-document-update.html
         */
        @Test
        public void update() throws IOException {
            UpdateRequest request = new UpdateRequest("fzk", "1");
            Person person = new Person("fzk", 20);
            request.doc(JSON.toJSONString(person), XContentType.JSON);
            UpdateResponse update = client.update(request, RequestOptions.DEFAULT);
            System.out.println(update.status());
        }
    
    
        /**
         * 删除文档内容
         * 参考地址:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/java-rest-high-document-delete.html
         */
        @Test
        public void delete() throws IOException {
            DeleteRequest request = new DeleteRequest("fzk", "1");
            DeleteResponse delete = client.delete(request, RequestOptions.DEFAULT);
            System.out.println(delete.status());
        }
    
    
        /**
         * 批量添加内容
         * 参考地址:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.6/java-rest-high-document-bulk.html
         */
        @Test
        public void bulkAdd() throws IOException {
            List<Person> personList = new ArrayList<>();
            personList.add(new Person("fzk1", 1));
            personList.add(new Person("fzk2", 2));
            personList.add(new Person("fzk3", 3));
            personList.add(new Person("fzk4", 4));
            personList.add(new Person("fzk5", 5));
            personList.add(new Person("fzk6", 6));
            personList.add(new Person("fzk7", 7));
            personList.add(new Person("fzk8", 8));
            BulkRequest bulkRequest = new BulkRequest();
            for (int i = 0; i < personList.size(); i++) {
                bulkRequest.add(new IndexRequest("fzk")
                        .id("" + (i + 1))
                        .source(JSON.toJSONString(personList.get(i)), XContentType.JSON));
            }
            //批量处理
            BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
            System.out.println(bulk.status());
        }
    }
    



查询 API 的简单使用

  • 查询条件

    • QueryBuilders.xxxQuery():常用的
      • matchAllQuery() :查询所有
      • matchQuery(String name, Object text) :按条件查询
      • multiMatchQuery(Object text, String… fieldNames) : 查询多个条件
      • matchPhraseQuery(String name, Object text)
      • termQuery(String name, Object value) :精确查询
      • rangeQuery(String name) :范围查询
      • existsQuery(String name) : 是否存在查询
      • boolQuery() :布尔查询
        • must(QueryBuilder queryBuilder) :与 查询(&&)
        • mustNot(QueryBuilder queryBuilder) : 非 查询(!)
        • should(QueryBuilder queryBuilder) :或 查询(||)
        • filter(QueryBuilder queryBuilder) :过滤器查询
    @RunWith(SpringRunner.class)
    @SpringBootTest
    class SpringbootinitializrApplicationTests {
        
        @Autowired
        @Qualifier("restHighLevelClient")
        private RestHighLevelClient client;
    
        @Test
        public void query() throws IOException {
            //1、创建搜索请求
            SearchRequest searchRequest = new SearchRequest("fzk");
            
            //2、创建条件查询
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            
            //3、编写查询条件,QueryBuilders.xxxQuery() 的都是查询,查询思路和请求的命令行一样
                //单个条件查询
            MatchQueryBuilder query = QueryBuilders.matchQuery("name", "fzk1");
                //多个条件查询
            /*
            BoolQueryBuilder query = QueryBuilders.boolQuery();
            query.must(QueryBuilders.matchQuery("name", "fzk1"));
            query.must(QueryBuilders.matchQuery("age", "1"));
             */
            
            //4、将查询条件添加到 SearchSourceBuilder 中,并添加其他条件
            searchSourceBuilder.query(query);
                //分页
            searchSourceBuilder.from(0);  //从 0 开始
            searchSourceBuilder.size(2);  //到 0+2 结束
                //高亮
            HighlightBuilder highlightBuilder = new HighlightBuilder();  //创建高亮
            highlightBuilder.field("name");  //高亮的 “name” 字段
            highlightBuilder.requireFieldMatch(false);  //多个高亮显示
            highlightBuilder.preTags("<p style='color:red'>");  //前缀标签
            highlightBuilder.postTags("</p>");  //后缀标签
            searchSourceBuilder.highlighter(highlightBuilder);  //将 HighlightBuilder 加入到 SearchSourceBuilder
            
            //5、将 SearchSourceBuilder 添加到 SearchRequest 中
            searchRequest.source(searchSourceBuilder);
            
            //6、查询请求响应
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            
            //7、打印查询到的数据
            for (SearchHit hit : searchResponse.getHits().getHits()) {
                System.out.println(hit.getSourceAsMap());  //打印查询到的信息
                HighlightField highlightField = hit.getHighlightFields().get("name");  //高亮信息
                if(highlightField != null){
                    System.out.println(highlightField.fragments()[0]);  //打印高亮的数据
                }
                System.out.println("==================");
            }
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值