第4篇: Elasticsearch各版本特性总结及7.X增删改查实战

背景:目前国内有大量的公司都在使用 Elasticsearch,包括阿里、京东、滴滴、今日头条、小米、vivo等诸多知名公司。除了搜索功能之外,Elasticsearch还结合Kibana、Logstash、Elastic Stack还被广泛运用在大数据近实时分析领域,包括日志分析、指标监控等多个领域。

目录

1、 Elasticsearch各版本特性

1.1 8.X 版本主要新特性

1.2 7.X 版本主要新特性

1.3 6.X 版本主要新特性

1.4 5.X 版本主要新特性

2、7.X增删改查实战

2.1 Elasticsearch 安装

2.1.1 依赖基础环境

2.1.2 下载Elastiscearch压缩包

2.1.3 启动及测试

2.2 CRUD实操

2.2.1 POM依赖

2.2.2 创建连接

2.2.3 创建索引

2.2.5 添加文档

2.2.6 查询文档

2.2.7 修改文档

2.2.8 删除文档

2.2.9 附测试类及实体


在开时实战之前,老王先给大家介绍下ES各版本的特性。

为什么要单独讲这个内容呢?在实际业务当下,很多公司目前还停留在ES 6.X ,如果是一些传统型公司可能还在用5.X。 不升级到最新版本可能会有以下两方面的考虑:

1、新版本的稳定性有待验证 。
2、升级成本问题。一般是业务比较复杂而且改造的性价比不划算。公司不会投入太多研发成本去做这件事情。

所以,不管你是即将进入职场的新人,还是已驰骋职场多年的大佬。很可能你即将入职的公司会用到以上不同的ES版本,但这些都不重要,我们重点是要会学习ES的核心内容和常用API使用即可。

1、 Elasticsearch各版本特性

目前官方最新版本为8.2。Elasticsearch Guide [8.2] | Elastic

1.1 8.X 版本主要新特性

elasticsearch 8.0官方文档

1)Rest API相比较7.x而言做了比较大的改动(比如彻底删除_type),为了降低用户的升级成本,8.x会暂时的兼容7.x的请求。

2)默认开启安全配置(三层安全),并极大简化了开启安全需要的工作量,可以这么说:7.x开启安全需要10步复杂的步骤比如CA、证书签发、yml添加多个配置等等,8.x只需要一步即可)。

3)存储空间优化:对倒排文件使用新的编码集,对于keyword、match_only_text、text类型字段有效,有3.5%的空间优化提升,对于新建索引和segment自动生效。
优化geo_point,geo_shape类型的索引(写入)效率:15%的提升。

4)新特性:支持上传pyTorch模型,在ingest的时候使用。比如在写入电影评论的时候,如果我们想要知道这个评论的感情正负得分,可以使用对应的AI感情模型对评论进行运算,将结果一并保存在ES中。

5) 技术预览版KNN API发布,(K邻近算法),跟推荐系统、自然语言排名相关。之前的KNN是精确搜索,在大数据集合的情况会比较慢,新的KNN提供近似KNN搜索,以提高速度。
6)对ES内置索引的保护加强了。elastic用户默认只能读,如果需要写权限的时候,需有allow_restrict_access权限。

1.2 7.X 版本主要新特性

elasticsearch 7.0官方文档

1) ES 数据库的存储结构变化,去除了Type, 默认的_doc作为type。
2) 默认配置变化:默认节点名称为主机名,默认分片数为1,不再是5。

3)彻底废除 _all 字段的支持,为提升性能默认不在支持全文检索。

4)自带jdk,所以在安装ES时不再需要单独下载和配置JAVA_HOME。

5)新增应用程序主动检测功能,搭配对应版本的kibana,用户可监测应用服务的健康状态,并在出现问题后及时发出通知。

6)时间戳纳秒级支持,提升数据精度。

7)不会再有OOM(内存溢出)的情况,JVM引入了新的circuit breaker(熔断)机制,当查询或聚合的数据量超过单机处理的最大内存限制时会被截断,并抛出异常。

1.3 6.X 版本主要新特性

elasticsearch 6.0官方文档

1)一个index只能有一个type,推荐的type名是 _doc。

2) 字段类型(datatype)的string取消了,可以用text类型替代。

3)mapping parameters中的index只能接收一个bool值,true或者false。

4)Index-template inheritance,索引版本的继承,目前索引模板是所有匹配的都会合并,这样会造成索引模板有一些冲突问题, 6.0 将会只匹配一个,索引创建时也会进行验证。

5)Load aware shard routing, 基于负载的请求路由,目前的搜索请求是全节点轮询,那么性能最慢的节点往往会造成整体的延迟增加,新的实现方式将基于队列的耗费时间自动调节队列长度,负载高的节点的队列长度将减少,让其他节点分摊更多的压力,搜索和索引都将基于这种机制。

6) 稀疏性 Doc Values 的支持:大家知道 es 的 doc values 是列式存储,文档的原始值都是存放在 doc values 里面的,而稀疏性是指,一个索引里面,文档的结构其实是多样性的,但是只要一个文档有这个字段,其他所有的文档尽管没有这个字段,可也都要承担这个字段的开销,所以会存在磁盘空间的浪费,而这块的改进就是这个问题。

7)无宕机升级:使之能够从 5 的最后一个版本滚动升级到 6 的最后一个版本,不需要集群的完整重启。无宕机在线升级,无缝滚动升级。

8)索引排序加快查询。通过索引排序,只要收集到足够的命中,搜索就可以终止。它对通常用作过滤器的低基数字段(例如 age, gender, is_published)进行排序时可以更高效的搜索,因为所有潜在的匹配文档都被分组在一起。

1.4 5.X 版本主要新特性

elasticsearch 5.0官方文档

1)Lucene 6.x 的支持。Elasticsearch5.0率先集成了Lucene6版本,其中最重要的特性就是 Dimensional Point Fields,多维浮点字段,ES里面相关的字段如date, numeric,ip 和 Geospatial 都将大大提升性能。磁盘空间少一半;索引时间少一半;查询性能提升25%;IPV6也支持了。

2)ES5.0在Internal engine级别移除了用于避免同一文档并发更新的竞争锁,带来15%-20%的性能提升。

2、7.X增删改查实战

2.1 Elasticsearch 安装

2.1.1 依赖基础环境

提前准备环境:JDK、IntelliJ IDEA、Maven、开发语言Java。~~自行搜索下载相关软件

2.1.2 下载Elastiscearch压缩包

下载路径:https://www.elastic.co/cn/downloads/past-releases/elasticsearch-7-9-3

 我用的是IOS系统,其余系统可自行选择。

18a0409dc50347efbdd83f0980f233f6.png

 下载压缩包后,直接解压到指定目录即可。

2.1.3 启动及测试

进入bin目录,执行命令:./elasticsearch &

测试地址:http://127.0.0.1:9200/

530be113de994ed3ad8f24e5fbd5b12a.png

 出现上图信息,表示启动成功。

2.2 CRUD实操

2.2.1 POM依赖

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.9.3</version>
    </dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.8.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.8.2</version>
</dependency>
<dependency>
<artifactId>fastjson</artifactId>
    <groupId>com.alibaba</groupId>
    <version>1.2.76</version>
</dependency>

2.2.2 创建连接

private static RestHighLevelClient restHighLevelClient;
static {
    restHighLevelClient = new RestHighLevelClient(
            RestClient.builder(new HttpHost("127.0.0.1", 9200, "http"))
    );
}

2.2.3 创建索引

索引格式:

{
  "mappings": {
    "properties": {
      "name": {
        "type": "keyword"
      },
      "createTime": {
        "format": "yyyy-MM-dd HH:mm:ss",
        "type": "date"
      }
    }
  }
}

创建索引: 

    /**
     * 创建索引
     * @param indexName 索引名称
     * @return
     * @throws IOException
     */
    public static Boolean createIndex(String indexName, String json) throws IOException {
        //创建索引请求
        CreateIndexRequest request = new CreateIndexRequest(indexName);
        // 创建索引JSON
        request.source(json, XContentType.JSON);
        //客户端执行请求 IndicesClient,请求后获得响应
        CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
        //输出是否创建成功
        return response.isAcknowledged();
    }

2.2.4 删除索引

 /**
     * 删除索引
     * @param indexName
     * @return
     * @throws IOException
     */
    public static Boolean deleteIndex(String indexName) throws IOException {
        //创建删除索引请求对象
        DeleteIndexRequest request = new DeleteIndexRequest(indexName);
        //客户端执行请求
        AcknowledgedResponse response = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
        //输出是否删除成功
        return response.isAcknowledged();
    }

2.2.5 添加文档

 /**
     * 添加文档
     * @param dto
     * @param indexName
     * @return
     * @throws IOException
     */
    public  static Boolean addDocument(Object dto, String indexName) throws IOException {
        BaseDto baseDto = (BaseDto) dto;
        //创建请求
        IndexRequest request = new IndexRequest(indexName);
        //规则 put
        request.id(baseDto.getId());
        request.timeout(TimeValue.timeValueSeconds(1));
        //将数据放入请求
        Map<String, Object> jsonMap = JSON.parseObject(toJson(dto), Map.class);
        request.source(jsonMap);
        //客户端发送请求
        IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
        //响应状态 CREATED
        return response.status().getStatus() == RestStatus.CREATED.getStatus();
    }

2.2.6 查询文档

 public static void search(String indexName) throws IOException {
        SearchRequest request = new SearchRequest(indexName);
        //构建搜索条件
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.sort("createTime", SortOrder.DESC);
        builder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        request.source(builder);
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        System.out.println(JSON.toJSONString(response.getHits()));
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

2.2.7 修改文档

    /**
     * 修改文档
     * @param dto
     * @param indexName
     * @return
     * @throws IOException
     */
    public static Boolean update(Object dto, String indexName) throws IOException {
        BaseDto baseDto = (BaseDto) dto;
        UpdateRequest updateRequest = new UpdateRequest();
        updateRequest.index(indexName);
        updateRequest.id(baseDto.getId());
        //将数据放入请求
        Map<String, Object> jsonMap = JSON.parseObject(toJson(dto), Map.class);
        updateRequest.doc(jsonMap);
        UpdateResponse response = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
        //响应状态 CREATED
        return response.status().getStatus() == RestStatus.OK.getStatus();
    }

2.2.8 删除文档

   public Boolean delete(String indexName, String id) throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest(indexName, id);
        DeleteResponse response = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        //响应状态 UPDATE
        return response.status().getStatus() == RestStatus.OK.getStatus();
    }

2.2.9 附测试类及实体

1)转Json工具类

 public static String toJson(Object text) {
        mapping.put(Date.class, new SimpleDateFormatSerializer(dateFormat));
        return JSON.toJSONString(text, mapping, SerializerFeature.DisableCircularReferenceDetect);
    }

2)实体类

import java.io.Serializable;

public class BaseDto implements Serializable {
    public String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

import java.util.Date;

public class TestEs extends BaseDto {
    private String name;
    private Date createTime;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
}

猜你喜欢

转载自blog.csdn.net/wangyongfei5000/article/details/124629783