Elasticsearch 学习

February 27th, 2020 by JasonLe's Tech Leave a reply »

elasticsearch 的层次结构和关系型数据库不一致,分为Index/【Type】/Document三个层级,对标Mysql就是:

ELK DB
Index Database
Type(已废弃) Table
Document Row
Column Filed
Schema Mapping
SQL DSL

在7.0以前,一个index会设置多个types,目前type已经废除,7.0后只允许创建一个type –> _doc

但是Document中es允许不同的结构,但是最好保持相同,这样有利于提高搜索效率。当我们插入一条数据后,如果没有指定_id的话,es会随机分配一个_id,如果强加指定的话,会按照该id存储Document。但是如果频繁对数据进行修改,随着插入数据的变多,自定义的_id会出现冲突的问题,可能在后期sharding出现查询缓慢的问题,需要额外注意。

至于移除type的原因主要是因为Lucene导致的,具体查看 https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html

分片可以分为主分片(primary key)和复制分片(replica shard)

主分片
每个文档都被分派到索引下的某个主分片内。
当索引创建完成时,主分片的数量就固定了。(这里存在一个问题,随着数量的增加,可能会出现不够的情况,最好保持一个shard<=30GB)
主分片的大小理论上是无限制的。
所有的写操作只能在主分片上完成后才能复制到其他分片上,写操作包括新建,索引,更新,删除。

复制分片
复制分片是主分片的副本,用以防止硬件故障导致的数据丢失。
复制分片可以提供读操作,比如搜索或从别的shared取回文档。
复制分片可以支持横向拓展。

Document 元数据,其中的_source是原JSON文件,_id 就是es中唯一标识的一个字段。

{
  "_index" : "movies",
  "_type" : "_doc",
  "_id" : "1163",
  "_version" : 1,
  "_seq_no" : 875,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "@version" : "1",
    "year" : 1994,
    "title" : "Mina Tannenbaum",
    "genre" : [
      "Drama"
    ],
    "id" : "1163"
  }
}

Document settings

{
  "movies" : {
    "settings" : {
      "index" : {
        "creation_date" : "1582618004949",
        "number_of_shards" : "1",
        "number_of_replicas" : "0",
        "uuid" : "JvyjYwMeTk6OmxhSRo-ocA",
        "version" : {
          "created" : "7060099"
        },
        "provided_name" : "movies"
      }
    }
  }
}

Document mappings

{
  "movies" : {
    "mappings" : {
      "properties" : {
        "@version" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        ......
    }
  }
}

从这个里面看到@version 字段 既可以全文匹配,也可以根据关键词匹配。

另外一个非常重要的功能就是 analyzer ,analyzer有现成的也有手写的,总的规则就是:

{
    "settings": {
        "analysis": {
            "char_filter": { ... custom character filters ... },//字符过滤器
            "tokenizer": { ... custom tokenizers ... },//分词器
            "filter": { ... custom token filters ... }, //词单元过滤器
            "analyzer":    { ...    custom analyzers      ... }
        }
    }
}

一个分词就是先对文档进行过滤(char_filter),然后进行分词(tokenizer),然后再对分词后的词进行过滤(filter),我们可以将这几个部分组装在analyzer中,然后放入setting,最后在mapping中引用my_analyzer即可。

{
    "settings": {
        "analysis": {
            "char_filter": {
                "&amp;amp;_to_and": {
                    "type": "mapping",
                    "mappings": [ "&amp;amp;=&amp;gt; and "]
            }},
            "filter": {
                "my_stopwords": {
                    "type": "stop",
                    "stopwords": [ "the", "a" ]
            }},
            "analyzer": {
                "my_analyzer": {
                    "type": "custom",
                    "char_filter": [ "html_strip", "&amp;amp;_to_and" ],
                    "tokenizer": "standard",
                    "filter": [ "lowercase", "my_stopwords" ]
            }}
}}}

CRUD就不用说了,除了可以使用Postman进行接口调试,也可以使用Kibana的Dev Tool

 

https://www.elastic.co/guide/index.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html