一、什么是Index Templates

帮助设定Mappings和Setting,并按照一定的规则,自动匹配到新创建的索引之上

  • 模板仅在一个索引被新创建时,才会产生作用。修改模板不会影响已创建的索引
  • 你可以设定多个索引模板,这些设置会被“merge”在一起
  • 你可以指定“oder”的数值,控制“merging”的过程

文档

二、Index Template的工作方式

当一个索引被创建时

  • 应用Elasticsearch默认的setting和mapping
  • 应用order数值低的Index Template中的设定
  • 应用order高的Index Template中的设定,之前的设定会被覆盖
  • 应用创建索引时,用户所指定的Setting和Mapping,并覆盖之前模板中的设定
PUT /_template/template_test
{
    "index_patterns" : ["test*"],
    "order" : 1,
    "settings" : {
        "number_of_shards": 1,
        "number_of_replicas" : 2
    },
    "mappings" : {
        "date_detection": false,
        "numeric_detection": true
    }
}
三、什么是Dynamic Template

根据Elasticsearch识别的数据类型,结合字段名称,来动态设定字段类型

  • 所有的字符串类型都设定成Keyword,或者关闭Keyword字段
  • is开头的字段都设置成boolean
  • long_开头的都设置成long类型

文档

四、Dynamic Template设定
  • Dynamic Template是定义在某个索引的Mapping中
  • Template有一个名称
  • 匹配规则是一个数组
  • 为匹配到字段设置Mapping
PUT my_index
{
  "mappings": {
    "dynamic_templates": [
            {
        "strings_as_boolean": {
          "match_mapping_type":   "string",
          "match":"is*",
          "mapping": {
            "type": "boolean"
          }
        }
      },
      {
        "strings_as_keywords": {
          "match_mapping_type":   "string",
          "mapping": {
            "type": "keyword"
          }
        }
      }
    ]
  }
}

更多设置 官网

字段类型设置

Index - 控制当前字段是否被索引。默认为true。如果设置成flase,该字段不可被搜索。

DELETE users
PUT users
{
    "mappings" : {
      "properties" : {
        "firstName" : {
          "type" : "text"
        },
        "lastName" : {
          "type" : "text"
        },
        "mobile" : {
          "type" : "text",
          "index": false
        }
      }
    }
}

null_value

  • 需要对Null值实现搜索
  • 只有Keyword类型支持设定Null_Value
PUT users
{
    "mappings" : {
      "properties" : {
        "firstName" : {
          "type" : "text"
        },
        "lastName" : {
          "type" : "text"
        },
        "mobile" : {
          "type" : "keyword",
          "null_value": "NULL"
        }
      }
    }
}

copy_to

  • copy_to将字段的数值拷贝到目标字段
  • copy_to的目标字段不出现在_source中
PUT users
{
  "mappings": {
    "properties": {
      "firstName":{
        "type": "text",
        "copy_to": "fullName"
      },
      "lastName":{
        "type": "text",
        "copy_to": "fullName"
      }
    }
  }
}
PUT users/_doc/1
{
  "firstName":"Ruan",
  "lastName": "Yiming"
}

GET users/_search?q=fullName:(Ruan Yiming)

POST users/_search
{
  "query": {
    "match": {
       "fullName":{
        "query": "Ruan Yiming",
        "operator": "and"
      }
    }
  }
}

数组类型

  • Elasticsearch中不提供专门的数组类型。但是任何字段,都可以包含多个相同类类型的数值。
PUT users/_doc/1
{
  "name":"onebird",
  "interests":"reading"
}

PUT users/_doc/1
{
  "name":"twobirds",
  "interests":["reading","music"]
}
多字段类型

多字段特性

  • 精确匹配:默认给每个text字段添加keyword字段
  • 使用不同的analyzer

    • 不同语言
    • pinyin字段搜索
    • 支持为搜索和索引指定不同的analyzer

Exact Values v.s Full Text

  • Exact Value:包括数字/日期/具体一个字符串(例如“Apple store”)

    • Elasticsearch中的keyword
  • 全文本,非结构话的文本数据

    • ELasticsearch中的text

full textand exact value.png

Exact Value在索引时不需要被分词

一、什么是Mapping

Mapping类似数据库中的schema的定义,作用如下

  • 定义索引中的字段的名称
  • 定义字段的数据类型,例如字符串,数字,布尔....
  • 字段,倒排索引的相关配置,(Analyzed or Not Analyzed,Analyzer)

Mapping会把JSON文档映射成Lucene所需要的扁平模式

二、Mapping的数据类型

1.简单类型

  • Text/Keyword
  • Date
  • Integer/Floating
  • Boolean
  • IPv4&IPv6

2.复杂类型-对象和嵌套对象

  • 对象类型/嵌套类型

3.特殊类型

  • geo_point&geo_shape/percolartor
三、Dynamic Mapping

1.写入文档时候,如果索引不存在,会自动创建索引

2.Dynamic Mapping的机制,使得我们无需手动定义Mappings。Elasticsearch会自动根据文档信息推算出字段的类型

3.有时候会推算的不对,例如地理位置信息

4.当类型如果设置不对时,会导致一些功能无法正常运行,例如Range查询。

leixingzidongshibie.png

四、修改Mapping的字段类型

1.新增加字段

  • Dynamic设为true时,一旦有新增字段的文档写入,Mapping也会同事被更新
  • Dynamic设为false,Mapping不会被更新,新增字段的数据无法被索引,但是信息会出现在_source中
  • Dynamic设置成strict,文档写入失败

2.对已有字段,一旦已经有数据写入,就不在支持修改字段定义

  • Lucene实现的倒排索引,一旦生成后,就不允许修改

3.如果希望修改字段类型,必须Reindex API,重建索引

  • 因为如果修改了字段的数据类型,会导致已被索引的无法被搜索
  • 但是如果是新增加的字段,就不会有这样的影响
五、自定义Mapping的方法

1.参考API手册,纯手写

2.也可以按照以下步骤

  • 创建一个临时的index,写入一些样本数据
  • 通过访问Mapping API获得该临时文件的动态Mapping定义
  • 修改后使用该配置创建自己的索引
  • 删除临时索引

集群身份认证需要跟集群内部安全通信一起配置不然会报错

一、集群身份认证

在elasticsearch.yml配置文件中加入

xpack.security.enabled: true
二、集群内部安全通信

1.生成证书

为Elasticsearch集群创建一个证书颁发机构。

bin/elasticsearch-certutil ca

2.为集群中的每个节点生成证书和私钥

bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12

可以在创建过程中加入密码

3.将证书拷贝到elasticsearch的每个节点下面config/certs目录下

elastic-certificates.p12

4.配置elasticsearch.yml文件

xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate

xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: certs/elastic-certificates.p12

5.如果在创建证书的过程中加了密码,需要将你的密码加入到你的Elasticsearch keystore中去。每个节点都需要

bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password

bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password
三、给认证的集群创建用户密码
bin/elasticsearch-setup-passwords interactive

通过第三步,可以给ES中许多内置的用户创建密码

  • elastic 账号:拥有 superuser 角色,是内置的超级用户。
  • kibana 账号:拥有 kibana_system 角色,用户 kibana 用来连接 elasticsearch 并与之通信。Kibana 服务器以该用户身份提交请求以访问集群监视 API 和 .kibana 索引。不能访问 index。
  • logstash_system 账号:拥有 logstash_system 角色。用户 Logstash 在 Elasticsearch 中存储监控信息时使用。
  • beats_system账号:拥有 beats_system 角色。用户 Beats 在 Elasticsearch 中存储监控信息时使用。

elastic是超级用户,它可以做任何事情

四、在Kibana中设置登录ES的用户

我们可以首先给Kibana配置上超级用户elastic,这样可以使用Kibana给ES集群配置不同的用户与角色。

  • 角色:我们可以给ES中的角色,赋予对不同索引的不同的读写权限。
  • 用户:我们可以将不同角色,赋予用户。

有两种方式使kibana访问ES集群。

  • 在Kibana.yml中配置
elasticsearch.username: "xxx"
elasticsearch.password: "xxx"
  • 使用Kibana.keystore
bin/kibana-keystore create
bin/kibana-keystore add elasticsearch.name
bin/kibana-keystore add elasticsearch.password
#删除
bin/kibana-keystore remove xxxx

登录Kibana设置角色跟用户

elasticsearch-security-blog-4.jpg

我们可以看到security下一个为设置用户一个为设置角色。

更多可查看

https://www.elastic.co/cn/blog/getting-started-with-elasticsearch-security

5.使用python连接设置好用户验证的ES集群

使用elasticsearch库

class ElasticSearchClient(object):
    # TODO:实例和事务化单个node,若需要多个node,需要重构代码
    def __init__(self):
        self.es_servers = [{
            "host": 'xx.xx.141.141',
            "port": '9200'
        }]
        self.es_client = elasticsearch.Elasticsearch(hosts=self.es_servers,http_auth=("xxxx", "xxxx"))#加入http_auth=("用户名","密码")
        # TODO:进行创建一个数据库,即index
    def create_es_index(self, index_name):
        self.es_client.indices.create(index=index_name)

    # TODO:进行删除一个数据库,即index
    def delete_es_index(self, index_name):
        self.es_client.indices.delete(index=index_name)

文档相关位置 官网

查询与索引流程中Analyzer的位置

1597047224.jpg

​ 我们从上图可以看出,Elasticsearch在倒排索引时会文本会使用设置的分析器,而输入的检索语句也会首先通过设置的相同分析器,然后在进行查询。

Analyzer的组成

分词器是专门处理分词的组件,由三部分组成

  • Character Filters(针对原始文本处理,例如去除html)
  • Tokenizer(按照规则切分为单词)
  • Token Filter(将切分的单词进行加工,小写,删除停用词,增加同义词等)
如何测试

1.直接指定Analyzer进行测试

GET _analyze
{
  "analyzer": "standard",
  "text": "2 running Quick brown-foxes leap over lazy dogs in the summer evening."
}

2.指定索引的字段进行测式

首先你要有这个索引与这个索引字段

POST books/_analyze
{
  "field": "title",
  "text": "2 running Quick brown-foxes leap over lazy dogs in the summer evening."
}

3.自定义分词器进行测试

GET _analyze
{
  "tokenizer": "standard",
  "filter":["lowercase"],
  "text": "2 running Quick brown-foxes leap over lazy dogs in the summer evening."
}
一些中文分词器
  • IK:支持自定义词库,支持热更新分词字典 ,地址
  • THULAC:清华的 地址
多字段类型

Elasticsearch可以在建立索引时给一个字段增加子字段让其适应不同格式检索,比如可以再子字段中添加设置不同的analyzer

duoziduan.png

自定义Analyzer

可以在创建索引时定义自己的分词器

PUT my_index

zidingyiana.png

PUT /artists/
{
    "settings" : {
        "analysis" : {
            "analyzer" : {
                "user_name_analyzer" : {
                    "tokenizer" : "whitespace",
                    "filter" : "pinyin_first_letter_and_full_pinyin_filter"
                }
            },
            "filter" : {
                "pinyin_first_letter_and_full_pinyin_filter" : {
                    "type" : "pinyin",
                    "keep_first_letter" : true,
                    "keep_full_pinyin" : false,
                    "keep_none_chinese" : true,
                    "keep_original" : false,
                    "limit_first_letter_length" : 16,
                    "lowercase" : true,
                    "trim_whitespace" : true,
                    "keep_none_chinese_in_first_letter" : true
                }
            }
        }
    }
}