ElasticSearch原理初探,倒排索引,使用SpringBoot操作ElasticSearch

为何要用ElasticSearch

    在最近的项目开发中,逐步接触到海量数据的搜索和可视化处理,Elasticsearch    是一个分布式、可扩展、实时的搜索与数据分析引擎。 它建立在一个全文搜索引擎库Apache Lucene基础之上,但隐藏了 Lucene中复杂的细节,使用ElasticSearch可以更高效的实现数据的搜索、分析和探索。Elasticsearch 不仅仅可以实现全文搜索还可以结构化搜索、数据分析、复杂的人类语言处理、地理位置和对象间关联关系等。 通过利用ElasticSearch的水平伸缩性,建立数据模型,并配置监控集群,将海量数据可实时分析,可视化。ES具有以下的特点:
    分布式文件存储,并将每一个字段都编入索引,使其可以实时搜索。
    速度和性能高,实时分析的分布式搜索引擎。全文搜索,结构化搜索,数据分析,ELKB数据可视化,和传统的数据库相比,它可以很快速的处理海量数据实现各种复杂的数据统计和搜索
    可扩展性高,支持PB级别海量数据分布式存储,支持数据分片,可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。

ElasticSearch搜索为什么会更快?

其一、因为ElasticSearch提供了强大的索引来提高搜索性能,Elasticsearch使用的倒排索引比关系型数据库的B-Tree索引快

  时间序列数据库分为两类,
        第一类的数据库按照关系型数据库
            [metric_name] [timestamp] [value]
        另外一类数据库其表结构是:
            [timestamp] [d1] [d2] .. [dn] [v1] [v2] .. [vn]
  ElasticSearch采用的正是倒排索引,在插入数据的同时,Elasticsearch还默默的为这些字段建立倒排索引,建立这些索引使得搜索变得高效快速,我们将建立的这些称为term,Elasticsearch为了能快速找到某个term,将所有的term排个序,二分法查找term,logN的查找效率,就像通过字典查找一样,这就是Term Dictionary,同时为了避免term dictionary过大,通过Term Index进行快速查找。当然,同时也会让数据的插入和修改操作效率变得更低,但是ElasticSearch的优势是传统数据库查询无法比拟的

其二、将磁盘里的东西尽量搬进内存,减少磁盘随机读取次数(同时也利用磁盘顺序读特性),结合压缩算法使用内存。

所以,对于使用Elasticsearch进行索引时需要注意:

不需要索引的字段,一定要明确定义出来,因为默认是自动建索引的
同样的道理,对于String类型的字段,不需要analysis的也需要明确定义出来,因为默认也是会analysis的
选择有规律的ID很重要,随机性太大的ID(比如java的UUID)不利于查询

ElasticSearch的应用场景

可以把Elasticsearch作为传统数据库的一个补充,比如全文检索,同义词处理,相关度排名,复杂数据分析,海量数据的近实时处理以及数据可视化,分布式日志数据搜索和分析等等;

例子:

扫描二维码关注公众号,回复: 10580854 查看本文章

维基百科搜素

The Guardian(国外新闻网站)

Stack Overflow(国外的程序异常讨论论坛)

GitHub(开源代码管理)

电商搜索系统

日志数据分析 ELK

商品价格数据监控

BI系统

站内搜索

使用SpringBoot操作ElasticSearch

引入相关依赖

<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>7.0.1</version>
</dependency>

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>7.0.1</version>
</dependency>
通过ElasticSearch官方提供的客户端进行操作
        RestHighLevelClient client=new RestHighLevelClient(RestClient.builder(
                new HttpHost(ips[0],port,"http"),
                new HttpHost(ips[1],port,"http"),
                new HttpHost(ips[0],port,"http")
         ));
        //向ElasticSearch添加文档
        Map<String, Object> jsonMap = new HashMap<>();
        jsonMap.put("username",people.getUsername());
        jsonMap.put("age", people.getAge());
        jsonMap.put("job", people.getJob());

        //创建并组装请求
        String uuId=UUIdUtils.getUUId();
        IndexRequest indexRequest = new IndexRequest("index01")
                .id(uuId).source(jsonMap);

        //定义监听器
        ActionListener listener=new ActionListener() {
            @Override
            public void onResponse(Object o) {
                //正确响应执行的方法
                System.out.println("成功添加文档到索引库");
            }

            @Override
            public void onFailure(Exception e) {
                System.out.println("添加文档到索引库失败");
            }
        };
        //添加文档
        client.indexAsync(indexRequest,RequestOptions.DEFAULT,listener);

        
        //查询
        String index="index01";

        //创建索引库的搜索请求对象
        SearchRequest searchRequest=new SearchRequest(index);

        //设置请求对象参数
        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();

        searchRequest.source(searchSourceBuilder);

        //建立客户端连接,根据请求对象搜索并获取搜索响应结果
        SearchResponse searchResponse=client.search(searchRequest, RequestOptions.DEFAULT);

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

当然这只是非常简单的操作,在工作中的项目开发可以根据项目的需求进行设计和封装,提高系统的可用性以及对大量并发请求的支持。

发布了117 篇原创文章 · 获赞 17 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/Jack__iT/article/details/100173646