Elasticsearch 学习笔记(下)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: Elasticsearch 学习笔记(下)
❤ 作者主页: 欢迎来到我的技术博客😎
❀ 个人介绍:大家好,本人热衷于 Java后端开发,欢迎来交流学习哦!( ̄▽ ̄)~*
🍊 如果文章对您有帮助,记得 关注点赞收藏评论⭐️⭐️⭐️
📣 您的支持将是我创作的动力,让我们一起加油进步吧!!!🎉🎉

一、IK分词器详解

1. IK分词器的定义

分词: 即把一段中文或别的划分成一个个的关键字,我们在搜索时候会把自己的信息进行分词,会把数据库中或者索引库中的数据进行分词,然后进行一个匹配操作,默认的中文分词是将每个字看成一个词,比如“我爱编程”会被分为“我”,“爱”,“编”,“程”,这显然是不符合要求的,所以我们需要安装中文分词器ik来解决这个问题。
IK提供了两个分词算法:ik_smartik_max_word,其中 ik_smart 为最小切分,ik_max_word 为最细粒度划分。

2. 安装

  1. 下载:https://github.com/medcl/elasticsearch-analysis-ik/releases
  2. 下载完成后,放入到我们的 elasticsearch 插件中即可。

在这里插入图片描述
 

  1. 重启观察ES,可以看到ik分词器被加载了

在这里插入图片描述
 

  1. elasticsearch-plugin 可以通过这个命令来查看加载进来的插件

在这里插入图片描述
 

  1. 使用kinaba测试

ik_smart
在这里插入图片描述
 
ik_max_word:
在这里插入图片描述

 
ik 分词器增加自己的配置: 添加自定义的词添加到扩展字典中。
在这里插入图片描述
 
重启es服务,再次进行测试:
在这里插入图片描述
在这里插入图片描述
 

二、Rest风格操作

1. Rest风格的定义

Rest 风格: 一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于 客户端和服务器交互类 的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

2. 基本Rest命令说明:

method url地址 描述
PUT(创建,修改) localhost:9200/索引名称/类型名称/文档id 创建文档(指定文档id)
POST(创建) localhost:9200/索引名称/类型名称 创建文档(随机文档id)
POST(修改) localhost:9200/索引名称/类型名称/文档id/_update 修改文档
DELETE(删除) localhost:9200/索引名称/类型名称/文档id 删除文档
GET(查询) localhost:9200/索引名称/类型名称/文档id 查询文档通过文档ID
POST(查询) localhost:9200/索引名称/类型名称/文档id/_search 查询所有数据

 

3. 关于索引的基本操作

  1. 创建索引(PUT)

在这里插入图片描述
 
指定字段的类型:
在这里插入图片描述
 

  1. 获取索引信息(GET)

在这里插入图片描述
 

  1. 修改

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
 

  1. 删除(DELETE)

通过 DELETE命令 实现删除,根据你的请求来判断是删除索引还是删除文档记录。
 

4. 关于文档的基本操作

  1. 添加数据

在这里插入图片描述

  1. 获取数据
  • 普通查询

在这里插入图片描述

  • 根据条件查询

在这里插入图片描述
 

5. 复杂查询

hit 里面包含了所有文档的具体信息。
在这里插入图片描述

 

  1. 过滤结果

在这里插入图片描述
 

  1. 排序

在这里插入图片描述
 

  1. 分页

在这里插入图片描述
 

  1. 多条件查询

在这里插入图片描述
 

  1. 过滤器filter

在这里插入图片描述

 

  1. 多条件查询

在这里插入图片描述
 

  1. 精确查询

term查询 是直接通过倒排索引指定的词条进程精确查找的。

关于分词:

  • term:直接查询精确的
  • match:会使用分词器解析。(先分析文档,然后通过分析的文档进行查询)

两种类型: textkeyword

PUT testdb
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "desc": {
        "type": "keyword"
      }
    }
  }
}

PUT testdb/_doc/1
{
  "name": "张三学Java name",
  "desc": "李四学Java desc"
}

PUT testdb/_doc/2
{
  "name": "张三学Java name",
  "desc": "李四学Java desc2"
}

 
在这里插入图片描述
在这里插入图片描述
 

  1. 高亮

在这里插入图片描述
 

  1. 自定义高亮的样式

在这里插入图片描述
 

三、SpringBoot集成ES详解

1. 导入依赖

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.14.0</version>
</dependency>

 
要保证导入的依赖和我们的es 版本一致:

<!--这边配置下自己对应的版本-->
<properties>
    <java.version>1.8</java.version>
    <elasticsearch.version>7.14.0</elasticsearch.version>
</properties>

 

2. 设置客户端对象

@Configuration
public class ElasticSearchClientConfig {

    @Bean
    public RestHighLevelClient restHighLevelClient() {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("127.0.0.1", 9200, "http"))
        );
        return client;
    }

}

 

核心配置类(源码):

// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
package org.springframework.boot.autoconfigure.elasticsearch;
import java.net.URI;
import java.net.URISyntaxException;
import java.time.Duration;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnClass({RestHighLevelClient.class})
@ConditionalOnMissingBean({RestClient.class})
@EnableConfigurationProperties({ElasticsearchRestClientProperties.class})
public class ElasticsearchRestClientAutoConfiguration {
    public ElasticsearchRestClientAutoConfiguration() {
    }
    private static class PropertiesCredentialsProvider extends BasicCredentialsProvider {
        PropertiesCredentialsProvider(ElasticsearchRestClientProperties properties) {
            if (StringUtils.hasText(properties.getUsername())) {
                Credentials credentials = new UsernamePasswordCredentials(properties.getUsername(), properties.getPassword());
                this.setCredentials(AuthScope.ANY, credentials);
            }
            properties.getUris().stream().map(this::toUri).filter(this::hasUserInfo).forEach(this::addUserInfoCredentials);
        }
        private URI toUri(String uri) {
            try {
                return URI.create(uri);
            } catch (IllegalArgumentException var3) {
                return null;
            }
        }
        private boolean hasUserInfo(URI uri) {
            return uri != null && StringUtils.hasLength(uri.getUserInfo());
        }
        private void addUserInfoCredentials(URI uri) {
            AuthScope authScope = new AuthScope(uri.getHost(), uri.getPort());
            Credentials credentials = this.createUserInfoCredentials(uri.getUserInfo());
            this.setCredentials(authScope, credentials);
        }
        private Credentials createUserInfoCredentials(String userInfo) {
            int delimiter = userInfo.indexOf(":");
            if (delimiter == -1) {
                return new UsernamePasswordCredentials(userInfo, (String)null);
            } else {
                String username = userInfo.substring(0, delimiter);
                String password = userInfo.substring(delimiter + 1);
                return new UsernamePasswordCredentials(username, password);
            }
        }
    }
    static class DefaultRestClientBuilderCustomizer implements RestClientBuilderCustomizer {
        private static final PropertyMapper map = PropertyMapper.get();
        private final ElasticsearchRestClientProperties properties;
        DefaultRestClientBuilderCustomizer(ElasticsearchRestClientProperties properties) {
            this.properties = properties;
        }
        public void customize(RestClientBuilder builder) {
        }
        public void customize(HttpAsyncClientBuilder builder) {
            builder.setDefaultCredentialsProvider(new ElasticsearchRestClientAutoConfiguration.PropertiesCredentialsProvider(this.properties));
        }
        public void customize(Builder builder) {
            PropertyMapper var10000 = map;
            ElasticsearchRestClientProperties var10001 = this.properties;
            var10001.getClass();
            var10000.from(var10001::getConnectionTimeout).whenNonNull().asInt(Duration::toMillis).to(builder::setConnectTimeout);
            var10000 = map;
            var10001 = this.properties;
            var10001.getClass();
            var10000.from(var10001::getReadTimeout).whenNonNull().asInt(Duration::toMillis).to(builder::setSocketTimeout);
        }
    }
    @Configuration(
        proxyBeanMethods = false
    )
    @ConditionalOnMissingBean({RestHighLevelClient.class})
    static class RestHighLevelClientConfiguration {
        RestHighLevelClientConfiguration() {
        }
        // RestHighLevelClient 高级客户端,也是我们这里要讲,后面项目会用到客户端
        @Bean
        RestHighLevelClient elasticsearchRestHighLevelClient(RestClientBuilder restClientBuilder) {
            return new RestHighLevelClient(restClientBuilder);
        }
    }
    @Configuration(
        proxyBeanMethods = false
    )
    @ConditionalOnMissingBean({RestClientBuilder.class})
    static class RestClientBuilderConfiguration {
        RestClientBuilderConfiguration() {
        }
        @Bean
        RestClientBuilderCustomizer defaultRestClientBuilderCustomizer(ElasticsearchRestClientProperties properties) {
            return new ElasticsearchRestClientAutoConfiguration.DefaultRestClientBuilderCustomizer(properties);
        }
        // RestClientBuilder
        @Bean
        RestClientBuilder elasticsearchRestClientBuilder(ElasticsearchRestClientProperties properties, ObjectProvider<RestClientBuilderCustomizer> builderCustomizers) {
            HttpHost[] hosts = (HttpHost[])properties.getUris().stream().map(this::createHttpHost).toArray((x$0) -> {
                return new HttpHost[x$0];
            });
            RestClientBuilder builder = RestClient.builder(hosts);
            builder.setHttpClientConfigCallback((httpClientBuilder) -> {
                builderCustomizers.orderedStream().forEach((customizer) -> {
                    customizer.customize(httpClientBuilder);
                });
                return httpClientBuilder;
            });
            builder.setRequestConfigCallback((requestConfigBuilder) -> {
                builderCustomizers.orderedStream().forEach((customizer) -> {
                    customizer.customize(requestConfigBuilder);
                });
                return requestConfigBuilder;
            });
            builderCustomizers.orderedStream().forEach((customizer) -> {
                customizer.customize(builder);
            });
            return builder;
        }
        private HttpHost createHttpHost(String uri) {
            try {
                return this.createHttpHost(URI.create(uri));
            } catch (IllegalArgumentException var3) {
                return HttpHost.create(uri);
            }
        }
        private HttpHost createHttpHost(URI uri) {
            if (!StringUtils.hasLength(uri.getUserInfo())) {
                return HttpHost.create(uri.toString());
            } else {
                try {
                    return HttpHost.create((new URI(uri.getScheme(), (String)null, uri.getHost(), uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment())).toString());
                } catch (URISyntaxException var3) {
                    throw new IllegalStateException(var3);
                }
            }
        }
    }
}

 

3. 关于索引的API操作详解

@SpringBootTest
class EsApiApplicationTests {

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

    @Test
    void testCreateIndex() throws IOException {

        // 1、创建索引请求
        CreateIndexRequest request = new CreateIndexRequest("kuang_index");

        // 2、客户端执行请求 indexResponse, 请求后获得相应
        CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
        System.out.println(createIndexResponse);
    }

    // 测试获取索引,只能判断其是否存在 查
    @Test
    void testExistIndex() throws IOException {
        GetIndexRequest request = new GetIndexRequest("kuang_index");
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
    }

    // 删除索引
    @Test
    void testDeleteIndex() throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest("kuang_index");
        AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
        System.out.println(delete.isAcknowledged());
    }
}

 

4. 关于文档的API操作详解

// 测试创建文档
    @Test
    void testAddDocument() throws IOException {
        // 创建对象
        User user = new User("狂神说", 3);
        // 索引请求
        IndexRequest request = new IndexRequest("kuang_index");
        // 规则 put /kuang_index/_doc/1
        request.id("1");
        request.timeout(TimeValue.timeValueDays(1));
        //    request.timeout("1");
        // 将我们的数据放入请求 json
        request.source(JSON.toJSONString(user), XContentType.JSON);
        // 客户端发送请求,获取响应结果
        IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
        System.out.println(indexResponse.toString());
        System.out.println(indexResponse.status());
    }

    // 获取文档,判断是否存在 get /index/doc/1
    @Test
    void testIsExists() throws IOException {
        GetRequest request = new GetRequest("kuang_index", "1");
        // 不获取返回的 _source 的上下文了
        request.fetchSourceContext(new FetchSourceContext(false));
        request.storedFields("_none_");
        boolean exists = client.exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
    }

    // 获取文档信息
    @Test
    void testGetDocument() throws IOException {
        GetRequest request = new GetRequest("kuang_index", "1");
        GetResponse getResponse = client.get(request, RequestOptions.DEFAULT);
        System.out.println(getResponse.getSourceAsString()); // 打印文档的内容
        System.out.println(getResponse);  // 返回的全部内容和命令是一样的
    }

    // 更新文档的信息
    @Test
    void testUpdateDocument() throws IOException {
        UpdateRequest updateRequest = new UpdateRequest("kuang_index", "1");
        updateRequest.timeout("1s");
        User user = new User("狂神说java", 18);
        updateRequest.doc(JSON.toJSONString(user), XContentType.JSON);
        UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println(updateResponse.status());
    }

    // 删除文档记录
    @Test
    void testDeleteRequest() throws IOException {
        DeleteRequest request = new DeleteRequest("kuang_index", "3");
        request.timeout("1s");
        DeleteResponse delete = client.delete(request, RequestOptions.DEFAULT);
        System.out.println(delete.status());
    }

    // 批量插入
    @Test
    void testBulkRequest() throws IOException {
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("10s");
        ArrayList<User> list = new ArrayList<>();
        list.add(new User("kuangshen1", 3));
        list.add(new User("kuangshen2", 3));
        list.add(new User("kuangshen3", 3));
        list.add(new User("qinjiang1", 3));
        list.add(new User("qinjiang2", 3));
        list.add(new User("qinjiang3", 3));
        // 批处理请求
        for (int i = 0; i < list.size(); i++) {
            // 批量更新和批量删除,就在这里修改对应的请求就可以了
            bulkRequest.add(
                    new IndexRequest("kuang_index")
                            .id("" + (i + 1))
                            .source(JSON.toJSONString(list.get(i)), XContentType.JSON));
        }
        BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
        System.out.println(bulkResponse.hasFailures());  // 是否失败,返回false代表成功
    }

    // 查询
    // HighLightBuilder 构建高亮
    // MatchAllQueryBuilder
    // xxx QueryBuilder 对应我们刚才看到的命令!
    @Test
    void testSearch() throws IOException {
        // SearchRequest 搜索请求 
        SearchRequest searchRequest = new SearchRequest("kuang_index");
        //  SearchSourceBuilder 构建搜索条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        // TermQueryBuilder查询条件,我们可以使用 QueryBuilders 工具来实现
        // QueryBuilders.termQuery  精确
        // QueryBuilders.matchAllQuery 匹配所有
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "qinjiang1");
        // MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println(JSON.toJSONString(searchResponse.getHits()));
        System.out.println("===========================");
        for (SearchHit documentFields : searchResponse.getHits().getHits()) {
            System.out.println(documentFields.getSourceAsMap());
        }
    }

 
 
创作不易,如果有帮助到你,请给题解==点个赞和收藏==,让更多的人看到!!!
==关注博主==不迷路,内容持续更新中。

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
7月前
|
SQL JSON API
ELK技术栈 - Elasticsearch 学习笔记(三)
ELK技术栈 - Elasticsearch 学习笔记(三)
105 0
|
7月前
|
存储 JSON API
ELK技术栈 - Elasticsearch 学习笔记(二)
ELK技术栈 - Elasticsearch 学习笔记(二)
254 0
|
7月前
|
存储 SQL JSON
ELK技术栈 - Elasticsearch 学习笔记(一)
ELK技术栈 - Elasticsearch 学习笔记(一)
257 0
|
7月前
|
JSON 自然语言处理 开发工具
elasticsearch7.X学习笔记
elasticsearch7.X学习笔记
157 0
|
7月前
|
JSON 自然语言处理 负载均衡
数据库-Elasticsearch进阶学习笔记(集群、故障、扩容、简繁体、拼音等)
数据库-Elasticsearch进阶学习笔记(集群、故障、扩容、简繁体、拼音等)
89 0
|
7月前
|
运维 监控 搜索推荐
数据库-ElasticSearch学习笔记
数据库-ElasticSearch学习笔记
78 0
|
存储 搜索推荐 Java
Elasticsearch的配置学习笔记
Elasticsearch是一个基于Lucene的搜索服务器。它提供一个分布式多用户能力的全文搜索引擎,基于RESTful web接口,Elasticsearch是用Java语言开发的。
77 0
|
数据挖掘 BI 定位技术
ElasticSearch学习笔记(八) 聚合之Bucket详解
Elasticsearch 聚合(Aggregation)是 Elasticsearch 中用于处理搜索结果的重要工具之一。它可以帮助我们对搜索结果进行各种数据统计和分析,以便更好地理解搜索结果数据的特征和趋势。
239 2
|
自然语言处理 算法 Docker
ElasticSearch学习笔记(四) IK分词
前面了解了Elasticsearch中对索引及文档的基本操作。今天了解Es中非常重要的一个概念:分词。在 Elasticsearch 中,中文分词的首选分词器是 ik 分词器。在本文中,我们将介绍如何使用 ik 分词器将商品名称(name)字段进行分词,并详细介绍分词过程及结果等。
571 2
|
JSON 数据挖掘 API
ElasticSearch学习笔记(三) Es文档基础操作
在Elasticsearch中,文档是索引的基本单位。一个文档代表了一个JSON对象,它包含了一个或多个字段,每个字段有一个字段名和一个字段值。一个索引可以包含多个文档,每个文档都有一个唯一的ID。
318 2