2019年11月

更多设置 官网

字段类型设置

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
                }
            }
        }
    }
}

ES中的倒排索引与相关性算法计算(TF-IDF/BM25)

一、倒排索引

daopai.png

上图所示左边为正常索引,右边为倒排索引。

倒排索引的核心组成

  • 单词词典(Term Dictionary),记录所有文档的单词,记录单词到到排列表的关联关系。

    • 单词词典一般比较大,可以通过B+树或者哈希拉链法实现,以满足高性能的插入与查询
  • 倒排列表(Posting List)-记录了单词对应的文档结合,由倒排索引项组成

    • 倒排索引项

      • 文档ID
      • 词频TF - 该单词在文档中出现的次数,用于相关性评分
      • 位置(Position) - 单词在文档中分词的位置。用于语句搜索(phrase query)
      • 偏移(offset) - 记录单词的开始结束位置,实现高亮显示

es倒排索引.png

​ 单词Elasticsearch的倒排索引列表

二、相关性与相关性算分

相关性-Relevance

  • 搜索的相关性算分,描述了一个文档和查询语句的匹配程度。ES会对每个匹配查询条件的结果进行算分_score
  • 打分的本质是排序,需要把最符合用户需求的文档排在前面。ES5之前,默认的相关性算分采用TF-IDF,现在采用BM25

词频TF

Term Frequency:检索此在一篇文档中出现的频率

  • 检索词出现的次数除以文档的总字数

度量一条查询和结果文档相关性的简单方法:简单将搜索中的每一个词的TF进行想加,例如:查询 区块链的应用

  • TF(区块链)+TF(的)+TF(应用)

Stop Word

  • “的”在文档中出现了很多次,但是对贡献相关度几乎没有用处,不应该考虑他们的TF

逆文档频率(IDF)

DF:检索词在所有文档中出现的频率

  • “区块链”在相对比较少的文档中出现
  • “应用”在相对比较多的文档中出现
  • “stop word”在大量文档中出现

Inverse Document Frequency:简单说=log(全部文档数/检索词出现过的文档总数)

TF-IDF本质上就是将TF求和变成了加权求和

  • TF(区块链)*IDF(区块链)+TF(的)* IDF(的)+TF(区块链)*IDF(区块链)

TF-IDF.png

TFid公式.png

BM25

TFbm25.png

定制Similarity计算公式

定制评分公式.png

查询小助手

可以通过“explain”参数查看打分状况

POST /testscore/_search
{
  //"explain": true,
  "query": {
    "match": {
      "content":"you"
      //"content": "elasticsearch"
      //"content":"the"
      //"content": "the elasticsearch"
    }
  }
}

使用boost控制相关度评分

boost.png

参考极客时间elasticsearch视频