zoukankan      html  css  js  c++  java
  • ElasticSearch基础+文档CRUD操作

                 本篇博客是上一篇的延续,主要用来将年前学习ES的知识点做一个回顾,方便日后进行复习和汇总!因为近期项目中使用ES出现了点小问题,因此在这里做一个详细的汇总!

    【01】全文检索和Lucene

    (1)全文检索,倒排索引
    (2)lucene,就是一个jar包,里面包含了封装好的各种建立倒排索引,以及进行搜索的代码,包括各种算法。我们就用java开发的时候,引入lucene jar,然后基于lucene的api进行去进行开发就可以了。用lucene,我们就可以去将已有的数据建立索引,lucene会在本地磁盘上面,给我们组织索引的数据结构。来看下面的图就明白了:

    【02】Elasticsearch的功能

     
    (1)分布式的搜索引擎和数据分析引擎
     
    搜索:百度,网站的站内搜索,IT系统的检索
    数据分析:电商网站,最近7天牙膏这种商品销量排名前10的商家有哪些;新闻网站,最近1个月访问量排名前3的新闻版块是哪些
    分布式,搜索,数据分析
     
    (2)全文检索,结构化检索,数据分析
     
    全文检索:我想搜索商品名称包含牙膏的商品,select * from products where product_name like "%牙膏%"
    结构化检索:我想搜索商品分类为日化用品的商品都有哪些,select * from products where category_id='日化用品'
    部分匹配、自动完成、搜索纠错、搜索推荐
    数据分析:我们分析每一个商品分类下有多少个商品,select category_id,count(*) from products group by category_id
     
    (3)对海量数据进行近实时的处理
     
    分布式:ES自动可以将海量数据分散到多台服务器上去存储和检索
    海联数据的处理:分布式以后,就可以采用大量的服务器去存储和检索数据,自然而然就可以实现海量数据的处理了
    近实时:检索个数据要花费1小时(这就不要近实时,离线批处理,batch-processing);在秒级别对数据进行搜索和分析
     
    跟分布式/海量数据相反的:lucene,单机应用,只能在单台服务器上使用,最多只能处理单台服务器可以处理的数据量

    【03】Elasticsearch的特点

    (1)可以作为一个大型分布式集群(数百台服务器)技术,处理PB级数据,服务大公司;也可以运行在单机上,服务小公司
    (2)Elasticsearch不是什么新技术,主要是将全文检索、数据分析以及分布式技术,合并在了一起,才形成了独一无二的ES;lucene(全文检索),商用的数据分析软件(也是有的),分布式数据库(mycat)
    (3)对用户而言,是开箱即用的,非常简单,作为中小型的应用,直接3分钟部署一下ES,就可以作为生产环境的系统来使用了,数据量不大,操作不是太复杂
    (4)数据库的功能面对很多领域是不够用的(事务,还有各种联机事务型的操作);特殊的功能,比如全文检索,同义词处理,相关度排名,复杂数据分析,海量数据的近实时处理;Elasticsearch作为传统数据库的一个补充,提供了数据库所不能提供的很多功能。

    【04】elasticsearch的核心概念

    (1)Near Realtime(NRT):近实时,两个意思,从写入数据到数据可以被搜索到有一个小延迟(大概1秒);基于es执行搜索和分析可以达到秒级:
    (2)Cluster:集群,包含多个节点,每个节点属于哪个集群是通过一个配置(集群名称,默认是elasticsearch)来决定的,对于中小型应用来说,刚开始一个集群就一个节点很正常
     
    (3)Node:节点,集群中的一个节点,节点也有一个名称(默认是随机分配的),节点名称很重要(在执行运维管理操作的时候),默认节点会去加入一个名称为“elasticsearch”的集群,如果直接启动一堆节点,那么它们会自动组成一个elasticsearch集群,当然一个节点也可以组成一个elasticsearch集群
     
    (4)Document&field:文档,es中的最小数据单元,一个document可以是一条客户数据,一条商品分类数据,一条订单数据,通常用JSON数据结构表示,每个index下的type中,都可以去存储多个document。一个document里面有多个field,每个field就是一个数据字段。
    相当于数据库中的一行
    product document
    {
      "product_id": "1",
      "product_name": "高露洁牙膏",
      "product_desc": "高效美白",
      "category_id": "2",
      "category_name": "日化用品"
    }
    (5)Index:索引,包含一堆有相似结构的文档数据,比如可以有一个客户索引,商品分类索引,订单索引,
    索引有一个名称。一个index包含很多document,一个index就代表了一类类似的或者相同的document。
    比如说建立一个product index,商品索引,里面可能就存放了所有的商品数据,所有的商品document。
    相当于关系型数据库中的一个库
     
    (6)Type:类型,每个索引里都可以有一个或多个type,type是index中的一个逻辑数据分类,
    一个type下的document,都有相同的field,比如博客系统,有一个索引,可以定义用户数据type,
    博客数据type,评论数据type。相当于关系型数据库中的一个表
    ES与关系型数据库之间的类比关系如下:

    举个稍微形象点的例子:

    举个例子:
    商品index,里面存放了所有的商品数据,即商品document
    
    但是商品分很多种类,每个种类的document的field可能不太一样,比如说电器商品,可能还包含一些诸如
    售后时间范围这样的特殊field;生鲜商品,还包含一些诸如生鲜保质期之类的特殊field
    
    type,日化商品type,电器商品type,生鲜商品type 
    
    日化商品type:product_id,product_name,product_desc,category_id,category_name
    电器商品type:product_id,product_name,product_desc,category_id,category_name,service_period
    生鲜商品type:product_id,product_name,product_desc,category_id,category_name,eat_period
    
    每一个type里面,都会包含一堆document
    {
      "product_id": "2",
      "product_name": "长虹电视机",
      "product_desc": "4k高清",
      "category_id": "3",
      "category_name": "电器",
      "service_period": "1年"
    }
    {
      "product_id": "3",
      "product_name": "基围虾",
      "product_desc": "纯天然,冰岛产",
      "category_id": "4",
      "category_name": "生鲜",
      "eat_period": "7天"
    }

    因此归根结底就是index里面有很多个Type,而每个type又有很多document。即一个数据库(index)中有很多表(type),每张表中又有很多行数据(document)

    下面再来看ES中的两个核心概念:

    7)shard:单台机器无法存储大量数据,es可以将一个索引中的数据切分为多个shard,分布在多台服务器上存储。有了shard就可以横向扩展,存储更多数据,让搜索和分析等操作分布到多台服务器上去执行,提升吞吐量和性能。每个shard都是一个lucene index。
    (8)replica:任何一个服务器随时可能故障或宕机,此时shard可能就会丢失,因此可以为每个shard创建多个
    replica副本。replica可以在shard故障时提供备用服务,保证数据不丢失,多个replica还可以提升搜索操作的吞
    吐量和性能。primary shard(建立索引时一次设置,不能修改,默认5个),replica shard(随时修改数量,默认1个
    ),默认每个索引10个shard,5个primary shard,5个replica shard,最小的高可用配置,是2台服务器。
    ES规定primary shard和replica shard不能在同一个节点上。因此我们一般将ES搭建在两台服务器上

    通过如下的一张图就可以很清晰的明白上面的概念了:

    【05】ES的基本操作

    关于ES的安装网络上有很多博客,笔者在此不再赘述。

    (1)快速检查集群的健康状况
     
    es提供了一套api,叫做cat api,可以查看es中各种各样的数据
    GET /_cat/health?v 结果如下:
    epoch      timestamp cluster       status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
    1488006741 15:12:21  elasticsearch yellow          1         1      1   1    0    0        1             0                  -                 50.0%
     
    epoch      timestamp cluster       status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
    1488007113 15:18:33  elasticsearch green           2         2      2   1    0    0        0             0                  -                100.0%
     
    epoch      timestamp cluster       status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
    1488007216 15:20:16  elasticsearch yellow          1         1      1   1    0    0        1             0                  -                 50.0%

    如何快速了解集群的健康状况?green、yellow、red?

    green:每个索引的primary shard和replica shard都是active状态的
    yellow:每个索引的primary shard都是active状态的,但是部分replica shard不是active状态,处于不可用的状态
    red:不是所有索引的primary shard都是active状态的,部分索引有数据丢失了
    例如我们在本地测试时发现此时ES集群的状态时yellow:

    原因:

    我们现在就一个笔记本电脑,就启动了一个es进程,相当于就只有一个node。现在es中有一个index,就是kibana自己内置建立的index。由于默认的配置是给每个index分配5个
    primary shard和5个replica shard,而且primary shard和replica shard不能在同一台机器上(为了容错)。现在kibana自己建立的index是1个primary shard和1个
    replica shard。当前就一个node,所以只有1个primary shard被分配了和启动了,但是一个replica shard没有第二台机器去启动。

    索引操作:

    2)快速查看集群中有哪些索引
    
    GET /_cat/indices?v
    
    health status index   uuid                   pri rep docs.count docs.deleted store.size pri.store.size
    yellow open   .kibana rUm9n9wMRQCCrRDEhqneBg   1   1          1            0      3.1kb          3.1kb
    
    (3)简单的索引操作
    
    创建索引:PUT /test_index?pretty
    
    health status index      uuid                   pri rep docs.count docs.deleted store.size pri.store.size
    yellow open   test_index XmS9DTAtSkSZSwWhhGEKkQ   5   1          0            0       650b           650b
    yellow open   .kibana    rUm9n9wMRQCCrRDEhqneBg   1   1          1            0      3.1kb          3.1kb
    
    删除索引:DELETE /test_index?pretty
    
    health status index   uuid                   pri rep docs.count docs.deleted store.size pri.store.size
    yellow open   .kibana rUm9n9wMRQCCrRDEhqneBg   1   1          1            0      3.1kb          3.1kb

    基本的CRUD操作:

    【01】获取某个索引信息:GET lagou/_settings  获取lagou这个索引的信息
    【02】获取所有索引的信息:GET _all/_settings 也可以使用GET _settings
    【03】查看某几个指定索引的信息,这里有几点要注意的地方:指定索引之间的逗号不能有空格:

    如下才是正确的:

    【05】保存数据到索引里面来
    我们不需要先定义好Type和Index,直接使用PUT操作即可:

     然后去head插件中查看:

    我们来修改下地址和城市,结果如下:

     看到没有这里有个小坑,直接像上面那样修改会直接将原始数据的其他字段值全量覆盖,因此要想修改指定字段的值,我们需要在地址栏中指定_update关键字,同时在里面使用doc指定,需要修改哪个字段,相当于就是说需要修改文档中的哪个字段,如下所示:另外还要注意指定ID,表示我修改的是哪个document 。另外要注意修改字段的值使用的是post请求

    再来查看修改后的结果:

     【06】在上面我们创建索引时,指定了doc的ID,但有时候我们需要ES来为我们生成ID,而不是我们自己指定ID,例如我们新增另外一条数据,记住这里使用的是post新增一条数据,而不是put:

    可以看到我们在上面使用了POST新增了一条数据到type中,而且没有指定ID,ES为我们自动生成了ID。再来查看head插件:

    【07】获取指定的字段

    现在我想获取指定的字段,例如title和city:
    GET lagou/job/1?_source=title,city

    结果如下所示:

    获取所有的:GET lagou/job/1?_source= 结果如下:

     【08】删除操作

    1.删除doc 使用DELETE lagou/job/1表示删除id为1的doc,此时索引index和type,相当于就是删除表中的一条数据

     2.删除type ES5报错,说明它不能删除Type:

    3.删除索引,可以删除索引:

     再去head中查看,发现没有了拉钩这个索引:

     

     以上就是关于ES的基本增删改查操作。相关的命令汇总如下:

    GET lagou/_settings
    GET _all/_settings
    GET .kibana,lagou/_settings
    #
    PUT lagou/_settings
    {
      "number_of_replicas": 2
    }
    GET _all
    GET lagou
    
    POST lagou/job/1
    {
      "title": "python爬虫开发工程师",
      "salary_min": 15000,
      "city": "北京",
      "company":{
        "name": "百度",
        "company_adr": "北京市软件园3栋"
      },
      "publish_date": "2017-4-16",
      "comments":14
    }
    POST lagou/job/
    {
      "title": "python Django开发工程师",
      "salary_min": 20000,
      "city": "北京",
      "company":{
        "name": "美团",
        "company_adr": "北京市软件园"
      },
      "publish_date": "2017-4-16",
      "comments":20
    }
    POST lagou/job/1
    {
      "title": "python爬虫开发工程师",
      "salary_min": 15000,
      "city": "北京",
      "company":{
        "name": "百度",
        "company_adr": "北京市软件园3栋"
      },
      "publish_date": "2017-4-16",
      "comments":14
    }
    DELETE lagou/job/1
    GET lagou/job/1
  • 相关阅读:
    HTML技巧篇:如何让单行文本以及多行文本溢出时显示省略号(…)
    SpringMVC中响应json数据(异步传送)
    如何用Spring框架的<form:form>标签实现REST风格的增删改查操作
    如何使用REST请求风格
    Spring插件的安装与卸载---笔记
    元素 "context:component-scan" 的前缀 "context" 未绑定的解决方案
    简单的文件上传的下载(动态web项目)
    用简单的反射优化代码(动态web项目)
    json数据与Gson工具类的使用
    JSON简介
  • 原文地址:https://www.cnblogs.com/pyspark/p/8717171.html
Copyright © 2011-2022 走看看