ElasticSearch学习笔记

es数据

  • 抽象成为一个对象

重点

  • 默认的,一个文档中的每一个属性都是被索引的(有一个倒排索引)和可搜索的,没有倒排索引的属性时不能被检索的。
  • 一个搜索默认返回10条结果
  • 短语搜索:精确匹配一系列的单词或者短语
GET /megacorp/employee/_search
{
    "query": {
        "match_phrase": {
            "about": "rock climbing"
        }
    }
}
  • 高亮检索,并不能够解决我们的这个显示高亮的数据的想法,高亮显示还是有点用的
  • aggs类似于groupby
# https://www.jishux.com/p/ba02e27d28cd9c3b
# 使用聚合需要设置的属性为文本属性
PUT /ecommerce/_mapping/product
{
  "properties": {
    "tags": {
      "type": "text",
      "fielddata": true
    }
  }
}

原理

  • 索引实际上是指向一个或者多个物理分片的逻辑命名空间
  • 一个分片是一个底层的工作单元,保存了全部数据当中的一部分,一个分片是一个Lucene的实例,以及它本身就是一个完整的搜索引擎
  • 一个分片可以是主分片或者副本分片,索引内的任一文档都归属一个主分片,所以主分片的数目决定着索引能够保存的最大数据量
    • 技术上来说,一个主分片主打能够存储Integer.MAX_VALUE - 128个文档
    • 副本分片只是主分片的拷贝
    • 在索引建立的时候就已经确定了主分片数,但是副本分片数可以随时修改
    • 索引在默认情况下会分配5个主分片
    • 主分片数目决定了这个索引能够存储的最大数据量,但是读操作–搜索和返回数据可以同时被主分片或者副本分片处理,所以当你拥有越多的副本分片时,也将拥有越高的吞吐量
# 动态改变副本分片的数目
PUT /blogs/_settings
{
   "number_of_replicas" : 2
}

丢失了一个节点之后

  • 如果是主节点,选举出一个新的主节点,丢失节点的主分片对应的搜索也是不能用的,但是幸运的是,副本分片将会被提升为主分片,这时为yellow状态,需要生成指定数目的副本,变为green

_type

  • 允许在索引当中进行逻辑分区,不同的types的文档可能有不同的字段,但是最好能够非常相似

乐观并发控制

  • Elasticsearch是分布式的。当文档创建、更新或删除的时候,新的文档必须复制到集群当中的其他节点。Elasticsearch也是异步和并发的,这意味着这些复制请求被并行发送,并且到达目的地时也许顺序是乱的。需要一种方法确保文档的旧版本不会覆盖新的版本.
    • index,get,delete请求时每个文档都有一个_version
    • 请求可以带上version,如果现在es单重存储的不是请求的版本,会报错,接下来交给程序去处理(乐观并发控制)

搜索

  • 类似于SQL结构化查询
  • 全文检索
相关概念
  • 映射(Mapping): 描述数据在每个字段内如何存储
  • 分析(Analysis): 全文是如何处理使之可以被搜索的
  • 领域特定查询语言(Query DSL):

分页相关

  • 在分布式系统中,对结果排序的成本随分页的深度成指数上升。这就是web搜索引擎对任何查询都不要返回超过1000个结果的原因

映射和分析

精确值 vs 全文

分析与分析器

  • 字符过滤器:在分词前整理字符串,一个字符过滤器可以用来去掉HTML,或者将&转化为 and
  • 分期器:字符串被分词器分为单个的词条
  • token过滤器:词条按顺序通过每个token过滤器。这个过程可能会改变词条(例如,小写化Quick),删除词条a, and, the等无用词

什么时候使用分析器

  • 索引一个文档,它的全文域被分析成词条用来创建倒排索引。但是我们检索的时候,需要将查询字符串通过相同的分析过程。
  • 查询精确值时,不会分析查询字符串,而是搜索你指定的精确值
  • 当Elasticsearch在你的文档中检测到一个新的字符串域,它会自动设置其为一个全文字符串域,使用标准分析器对他进行分析
    • 如果你想使用一个不同的分析器,必须手动执行这些域的映射
  • 当你索引一个包含新域的文档,之前未曾出现,Elasticsearch会使用动态映射,通过JSON当中基本数据类型,尝试猜测域类型。
  • 类型的映射
  • 域最重要的属性是type,string类型域被认为包含全文
# 测试分析器
GET /_analyze
{
  "analyzer": "standard",
  "text": "Text to analyze"
}

复杂核心域类型

查询与过滤

  • 过滤情况时:不评分或者过滤查询,即这个查询只是简单的问一个问题”这篇文章是否匹配“,yes or no
  • 查询情况时:评分查询

处理人类语言

  • 自定义分析器

聚合

  • 指标

mapping

PUT cars/_mapping/transactions
{
  "properties": {
    "make": {
      "type": "text",
      "fielddata": true
    }
  }
}

聚合的写法

GET /cars/transactions/_search
{
  "size": 0,
  "aggs": {
    "colors": {
      "terms": {
        "field": "color"
      },
      "aggs": {
        "agg_price": {
          "avg": {
            "field": "price"
          }
        },
        "make": {
          "terms": {
            "field": "make"
          },
          "aggs": {
            "min_price": {"min": {"field": "price"}},
            "max_price": {"max": {"field": "price"}}
          }
        }
      }
    }
  }
}

# 更复杂的一个聚合
GET cars/transactions/_search
{
  "size": 0,
  "aggs": {
    "sales": {
      "date_histogram": {
        "field": "sold",
        "interval": "quarter",
        "format": "yyyy-MM-dd",
        "min_doc_count": 0,
        "extended_bounds": {
          "min": "2014-01-01",
          "max": "2014-12-31"
        }
      },
      "aggs": {
        "per_make_sum": {
          "terms": {
            "field": "make"
          },
          "aggs": {
            "per_make_sum": {
              "terms": {
                "field": "make"
              },
              "aggs": {
                "sum_price": {
                  "sum": {
                    "field": "price"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

实际当中的一些操作

# 根据id查询数据
GET zhuvideo/video/_search
{
  "query": {
    "ids": {
      "values": ["d98f6049c4eadcd023b029ff07a4174e", "205a27426ef2f3ae8a028ab2c69f6b9c"]
    }
  }
}

数据建模

父子文档

  • 创建的时机
    • 创建索引时
    • 在子文档type创建之前更新父文档的mapping
  • 在执行单文档的请求时,需要指定父文档的ID,因为在索引一个子文档的时候指定了父文档的ID,那么不在使用子文档的ID去索引了,单文档操作只会向存储改文档的分片发送请求
  • 执行搜索请求的时候是不需要指定父文档的ID的。因为搜索请求时想索引的所有分片发起请求
  • 慎用父子文档,查询速度非常慢

嵌套文档

  • 这个挺好用的

部署之后

  • id友好,可以提升效率,不要使用随机的id
{
    "words_en": [
        {
            "starttime": "00:00:00",
            "endtime": "00:12:00",
            "words": "hello world! hello",
            "words_ori": "hello word"
        }
    ]
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值