暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

ElasticSerach入门

码农私塾 2021-12-13
1202

微信公众号:码农私塾
关注可获得更多编程知识分享
如果你觉得文章对你有帮助,欢迎赞赏

目录

ElasticSerach简介ElasticSerach的应用场景ElasticSerach基本概念端口索引(Index)类型(Type)文档(Document)映射(Mapping)分片(Shards)副本(Replicas)docker-compose安装Elasticsearch集群docker-compose文件集群节点配置文件IK分词器java客户端操作Elasticsearch索引操作文档操作文档搜索总结

ElasticSerach简介

ElasticSerach简称为ES,是一个开源的高拓展的分布式全文搜索引擎,也是ELK技术的核心,可以近乎实时的存储,检索数据,可以处理PB级别的海量数据,提供了RESTful的http接口,各种编程语言都可以访问操作ES.

与传统sql数据库的差别在于,ES采用倒排索引,将存储的值使用算法分词,每个分词会记录包含这个分词的文档id,查找时 根据输入的关键词 查找倒排索引 快速定位到满足条件的数据 然后计算匹配度得到分值 用来排序结果

ElasticSerach的应用场景

Google,百度等网站搜索,它们都是根据网页中的关键字生成索引,我们在搜索的时候输入关键字,它们会将该关键字即索引匹配到的所有网页返回;还有常见的项目中应用日志的搜索等等。对于这些非结构化的数据文本,关系型数据库搜索不是能很好的支持。一般传统数据库,全文检索都实现的很鸡肋,因为一般也没人用数据库存文本字段。进行全文检索需要扫描整个表,如果数据量大的话即使对 SQL 的语法优化,也收效甚微。建 立了索引,但是维护起来也很麻烦,对于insert和update 操作都会重新构建索引。基于以上原因可以分析得出,在一些生产环境中,使用常规的搜索方式,性能是非常差

  1. 搜索的数据对象是大量的非结构化的文本数据。

  2. 文件记录量达到数十万或数百万个甚至更多。

  3. 支持大量基于交互式文本的查询。

  4. 需求非常灵活的全文搜索查询。

  5. 对高度相关的搜索结果的有特殊需求,但是没有可用的关系数据库可以满足。

这里说到的全文搜索引擎指的是目前广泛应用的主流搜索引擎。它的工作原理是计算机 索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的 次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反 馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程

ElasticSerach基本概念

端口

ES启动后会默认使用两个端口9200和9300,9200是提供Restful风格接口的端口,9300用于集群节点内部通信

索引(Index)

一个索引就是一个拥有几分相似特征的文档的集合。比如说,你可以有一个客户数据的 索引,另一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字来标识(必 须全部是小写字母),并且当我们要对这个索引中的文档进行索引、搜索、更新和删除的时 候,都要使用到这个名字。在一个集群中,可以定义任意多的索引。能搜索的数据必须索引,这样的好处是可以提高查询速度,比如:新华字典前面的目录 就是索引的意思,目录可以提高查询速度。
Elasticsearch 索引的精髓:一切设计都是为了提高搜索的性能

类型(Type)

在一个索引中,你可以定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类/分区,其语义完全由你来定。通常,会为具 有一组共同字段的文档定义一个类型,5.x版本支持多种类型,6.x支持一种类型,7.x以后不支持自定义类型默认类型为_doc

文档(Document)

一个文档是一个可被索引的基础信息单元,也就是一条数据 比如:你可以拥有某一个客户的文档,某一个产品的一个文档,当然,也可以拥有某个 订单的一个文档。文档以 JSON(Javascript Object Notation)格式来表示,而 JSON 是一个 到处存在的互联网数据交互格式。在一个 index或者type 里面,你可以存储任意多的文档。

映射(Mapping)

mapping 是处理数据的方式和规则方面做一些限制,如:某个字段的数据类型、默认值、 分析器、是否被索引等等。这些都是映射里面可以设置的,类似数据库的表结构限制一样,是建立在索引上的

分片(Shards)

一个索引可以存储超出单个节点硬件限制的大量数据。比如,一个具有 10 亿文档数据 的索引占据 1TB 的磁盘空间,而任一节点都可能没有这样大的磁盘空间。或者单个节点处 理搜索请求,响应太慢。为了解决这个问题,Elasticsearch 提供了将索引划分成多份的能力, 每一份就称之为分片。当你创建一个索引的时候,你可以指定你想要的分片的数量。每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上,有两个好处

  1. 允许你水平分割 / 扩展你的内容容量

  2. 允许你在分片之上进行分布式的、并行的操作,进而提高性能/吞吐量

数据的存储具体哪一个分片上的路由功能,由ES的分片算法决定,默认是hash(_id)%分片数量,也可以指定使用某个字段的值来进行hash运算

副本(Replicas)

在一个网络或者云的环境下,随时可能有某一个节点故障导致无法提供服务,这时候就需要故障转移机制,Elasticsearch 可以在创建索引时指定分片数量和副本数量 默认分片和副本数量都是1 副本数量可以随时修改,分片可以读写,副本只能读取 可以根据集群机器情况设置副本数量 提高吞吐量,
并且ES不允许分片和副本在同一个节点存储,所以一个集群至少得有2个节点

docker-compose安装Elasticsearch集群

docker-compose文件

 1version: "3"
2services:
3  es1:
4    image: elasticsearch:7.14.2
5    container_name: es1
6    environment:
7      - "ES_JAVA_OPTS=-Xms512M -Xmx512M" #配置jvm堆大小
8    volumes: #挂载配置文件 和数据目录
9      - E:\dockerData\elasticSearchCluster\es1\conf\elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
10      - E:\dockerData\elasticSearchCluster\es1\data:/usr/share/elasticsearch/data
11      - E:\dockerData\elasticSearchCluster\es1\plugins:/usr/share/elasticsearch/plugins
12    ports: #映射宿主机端口到容器端口
13      - 9200:9200
14      - 9300:9300
15    expose: #暴露这个端口
16      - 9200
17  es2:
18    image: elasticsearch:7.14.2
19    container_name: es2
20    environment:
21      - "ES_JAVA_OPTS=-Xms512M -Xmx512M" #配置jvm堆大小
22    volumes: #挂载配置文件 和数据目录
23      - E:\dockerData\elasticSearchCluster\es2\conf\elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
24      - E:\dockerData\elasticSearchCluster\es2\data:/usr/share/elasticsearch/data
25      - E:\dockerData\elasticSearchCluster\es2\plugins:/usr/share/elasticsearch/plugins
26    ports: #映射宿主机端口到容器端口
27      - 9201:9200
28      - 9301:9300
29    expose: #暴露这个端口
30      - 9201
31    depends_on:
32      - es1
33  es3:
34    image: elasticsearch:7.14.2
35    container_name: es3
36    environment:
37      - "ES_JAVA_OPTS=-Xms512M -Xmx512M" #配置jvm堆大小
38    volumes: #挂载配置文件 和数据目录
39      - E:\dockerData\elasticSearchCluster\es3\conf\elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
40      - E:\dockerData\elasticSearchCluster\es3\data:/usr/share/elasticsearch/data
41      - E:\dockerData\elasticSearchCluster\es3\plugins:/usr/share/elasticsearch/plugins
42    ports: #映射宿主机端口到容器端口
43      - 9202:9200
44      - 9302:9300
45    expose: #暴露这个端口
46      - 9202
47    depends_on:
48      - es2

集群节点配置文件

 1cluster.name: "esCluster"
2node.name: "es1"
3node.mastertrue #是否有资格为主节点
4node.datatrue #节点是否存储数据 
5http.cors.enabledtrue    #开启跨域访问 elasticSearch-head插件需要开启此功能
6http.cors.allow-origin: "*"
7cluster.initial_master_nodes["es1"] #集群初始化默认主节点
8network.host: 0.0.0.0
9discovery.zen.minimum_master_nodes: 2
10discovery.zen.ping.unicast.hosts["es1:9300", "es2:9301", "es3:9302"]#集群所有节点通信地址

IK分词器

ES是全文搜索引擎会建立倒排索引,就会涉及到将存储的文本进行拆分,默认的分词器不适合中文,IK分词器就是专门针对中文进行分词,下载地址

1https://github.com/medcl/elasticsearch-analysis-ik/releases

选择和es对应的版本下载即可,解压成文件夹放到es的plugins目录下即可,启动es会加载

IK分词器提供两种分词类型
ik_max_word:会将文本做最细粒度的拆分
ik_smart:会将文本做最粗粒度的拆分
如果需要自定义某几个字作为一个词,不想被拆分也可以自定义字典,在建立索引映射时可以给字段设置需要使用的分词器

java客户端操作Elasticsearch

es支持多种语言客户端包括java,目前新版主要使用Java High Level REST Client进行访问,Spring Data也提供了对应的子项目 spring data elasticSearch 以dao接口的设计模式 对Java High Level REST Client进行了封装 可以和使用操作sql数据库一样进行使用

索引操作

对于索引的操作都是封装在IndicesClient这个对象的方法,通过传入例如CreateIndexRequest,GetMappingsRequest这样的参数来实现具体的操作 而这个IndicesClient对象通过RestHighLevelClient的indices()方法获得

创建索引

 1  RestHighLevelClient highLevelClient=new RestHighLevelClient(RestClient.builder(new HttpHost("localhost"9200"http")));
2
3//指定索引名
4CreateIndexRequest request=new CreateIndexRequest("test");
5// 设置分片以及副本
6request.settings(Settings.builder() 
7    .put("index.number_of_shards"3)
8    .put("index.number_of_replicas"2)
9);
10//设置索引映射
11request.mapping("映射设置的json格式字符串",XContentType.JSON);
12 CreateIndexResponse createIndexResponse = highLevelClient.indices().create(request, RequestOptions.DEFAULT);
13  //创建状态
14   createIndexResponse.isAcknowledged()

查询索引

1  RestHighLevelClient highLevelClient=new RestHighLevelClient(RestClient.builder(new HttpHost("localhost"9200"http")));
2        //指定索引名
3        GetIndexRequest request=new GetIndexRequest("test");
4        GetIndexResponse getIndexResponse = highLevelClient.indices().get(request, RequestOptions.DEFAULT);
5        //获取索引分片和副本信息 以及映射信息
6        System.out.println(getIndexResponse.getSetting("test","index.number_of_shards"));
7        System.out.println(getIndexResponse.getSetting("test","index.number_of_replicas"));
8        System.out.println(getIndexResponse.getMappings().get("test").getSourceAsMap());

修改索引

 1 RestHighLevelClient highLevelClient=new RestHighLevelClient(RestClient.builder(new HttpHost("localhost"9200"http")));
2//修改索引映射
3        PutMappingRequest request = new PutMappingRequest("test");
4        request.source("映射json格式字符串", XContentType.JSON);
5        highLevelClient.indices().putMapping(request,RequestOptions.DEFAULT);
6        //修改副本数量
7        UpdateSettingsRequest request2 = new UpdateSettingsRequest("test");
8        String settingKey = "index.number_of_replicas";
9        int settingValue = 1;
10        Settings settings =
11                Settings.builder()
12                        .put(settingKey, settingValue)
13                        .build();
14        request2.settings(settings);
15        highLevelClient.indices().putSettings(request2,RequestOptions.DEFAULT);

文档操作

创建文档

 1 RestHighLevelClient highLevelClient=new RestHighLevelClient(RestClient.builder(new HttpHost("localhost"9200"http")));
2IndexRequest request=new IndexRequest("test");
3        //id 可不填 es自动生成
4        request.id(UUID.randomUUID().toString());
5        //设置要存储的文档值
6        request.source("{" +
7                "\"user\":\"kimchy\"," +
8                "\"postDate\":\"2013-01-30\"," +
9                "\"title\":\"trying out Elasticsearch\"" +
10                "}",XContentType.JSON);
11        IndexResponse index = highLevelClient.index(request, RequestOptions.DEFAULT);
12        //打印返回状态信息
13        System.out.println(index.toString());

批量创建

 1 RestHighLevelClient highLevelClient=new RestHighLevelClient(RestClient.builder(new HttpHost("localhost"9200"http")));
2  //这个对象是用于执行批量操作的 不止可以批量新增 还可以修改 删除
3  BulkRequest request = new BulkRequest();
4        for (int i = 0; i < 10; i++) {
5            request.add(new IndexRequest("test").source("{" +
6                    "\"user\":\"kimchy\"," +
7                    "\"postDate\":\"2013-01-30\"," +
8                    "\"title\":\"trying out Elasticsearch"+i+"\"" +
9                    "}",XContentType.JSON));
10        }
11        BulkResponse bulk = highLevelClient.bulk(request, RequestOptions.DEFAULT);

修改文档

1 RestHighLevelClient highLevelClient=new RestHighLevelClient(RestClient.builder(new HttpHost("localhost"9200"http")));
2       //根据文档id修改 部分值
3        UpdateRequest request = new UpdateRequest("test""49dec78f-cf84-481a-bc5e-b4f65c7e15cb");
4        request.doc("{\"title\":\"hello,world\"}",XContentType.JSON);
5        highLevelClient.update(request,RequestOptions.DEFAULT);

删除文档

1 RestHighLevelClient highLevelClient=new RestHighLevelClient(RestClient.builder(new HttpHost("localhost"9200"http")));
2//指定索引和文档id删除
3 DeleteRequest request=new DeleteRequest("test","49dec78f-cf84-481a-bc5e-b4f65c7e15cb");
4        highLevelClient.delete(request,RequestOptions.DEFAULT);

文档搜索

 1RestHighLevelClient highLevelClient=new RestHighLevelClient(RestClient.builder(new HttpHost("localhost"9200"http")));
2        //创建搜索请求 并指定搜索的索引
3        SearchRequest request=new SearchRequest("test");
4        //创建搜索条件构建器
5        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
6        //设置分页参数
7        searchSourceBuilder.from(0);
8        searchSourceBuilder.size(5);
9        //创建查询条件
10        QueryBuilder query = = QueryBuilders.matchAllQuery();
11        searchSourceBuilder.query(query);
12        request.source(searchSourceBuilder);
13        SearchResponse response = highLevelClient.search(request, RequestOptions.DEFAULT);
14        System.out.println(response.toString());

使用QueryBuilders这个工具类可以创建各种各类的QueryBuilder,可以用java代码的方式创建成es的Query DSL.相同的查询条件 可以参考官方文档

总结

ElasticSerach的版本更新非常快,并且API变动也比较大,所以很多时候都需要多去查看官网的文档

文章转载自码农私塾,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论