es学习

 

目录

getting startted

基本概念

Near Realtime(NRT)

Cluster

Node

index

document

shards & replicas

安装

暴露集群

cluster health 

集群健康状态

创建索引

delete index

modify data

update documents

批量处理: _bulk

load simple dataset

search 

1.参数放在request uri后面

2.参数在requrst body里面

query dsl

1.leaf query clauses

2.compound query clauses

查询指定索引里的所有文档

excuting search

匹配查询

bool 查询,must, should, must_not

executing filters

excuting aggregations

set up es

配置

创建keystore

logging 配置

审核安全设置

跨集群副本设置

es集群元素

搜索相关性排序算法

TF-IDF

TF(词频)

逆向文件频率

算法原理

 TF-IDF算法例子

额外的学习资料


官方参考手册:https://www.elastic.co/guide/en/elasticsearch/reference/7.1/index.html

getting startted

基本概念

Near Realtime(NRT)

近实时。

es是一个近实时的搜索平台。从检索文档到可搜索文档的时间大概有1秒的延时。

Cluster

集群。

集群是一个或多个节点(服务器)的集合,共同保存整个数据,并提供跨节点的联合索引和搜索功能。

集群由唯一的名称标识,默认为:elasticsearch。当这些节点设置成通过名称来加入集群的时候,集群名称就显得很重要。

确保在不同的环境下不要重复使用集群名称,否则就会把节点加入到错误的集群里面。比如,可以用logging-dev, logging-stage, logging-prod一次代表开发, 测试,生成的集群环境。

一个集群只有一个节点是可以的,也是很不错的。当然,也可以由多个独立的集群,每个集群由唯一的集群名称。

Node

节点。

节点是集群里面一个单独的服务器,存储数据,参与集群的索引和查询能力。跟集群类似,节点以名称标识,默认是改节点在启动时候随机分配的uuid。如果不想使用默认节点名称也可以自定义。节点名称对于管理目的很重要,当要识别网络中哪些服务于集群中哪些节点名称符合 的时候。

节点可以配置来按照集群名称加入特定的集群。默认情况下,每个节点都加入elasticsearch这个集群。这就意味着如果你在网络中启动了多个节点并假设他们可以彼此相互发现,这些节点就会自动形成并且加入到elasticsearch这个集群。

在当集群中,可以拥有任意数量的节点。另外,如果当前网络上没有其他es节点正在运行,默认启动的单个节点将形成一个名为elasticsearch的新但节点集群。

index

索引

一个index是具有某些相似特征的文档的集合。比如,一个customer data的index, product data的index,或者其他order index。

索引由名称标识,必须全部小写。索引名称用来在对文档进行索引,搜索,更新,删除的时候进行引用。

单个集群中,可以定义任意数量的索引。

document

文档。

是可以被检索的基本信息单元。如,有一个文档是单个customer ,一个文档是单个product,还有一个文档是单个order。

文档以json格式表示。在索引中,可以按需存储任意数量的文档。

shards & replicas

碎片和副本。

shard

一个index可能存储大量的数据超过当节点的硬件限制。

es将index细分为shard。

在创建index,只需要定义需要的shard数量即可。每个shard都是一个功能齐全且独立的"index",可以托管在集群的任意节点。

允许水平分割/缩放容量

允许跨shard(可能在多个节点)分布和并行化操作,提供性能/吞吐量。

shard的分布方式以及如何将文档聚合是es管理,对用户透明。

副本

在shard/节点出现故障时提供高可用。请务必注意,副本分片永远不会在与从中复制的原始/主分片相同的节点上分配。

允许扩展搜索量/吞吐量,因为可以在所有副本上并行执行搜索。

总而言之,每个Index可以被拆分为多个shard。每个index也可以被复制0次或多次。。一旦被复制,每个index将有一个主shards(从中复制的原始的shard)和副shards(主shards的副本)。

在创建index的时候定义shards和replicas的数量。在创建后可以随时动态更改replicas数量。

可以使用_shrink和_split api来更新现有的shards数量。(需要预先计划正确的shards数量)

默认情况下,es为每个index都分配了一个主shards和一个replicas。意味着如果集群中至少2个节点,则index将由一个主shards和一个副本shards.

安装

https://blog.csdn.net/wslixiaoliang/article/details/80688090

暴露集群

rest api

1.检查cluster,node,index的health, status, statistics

2.管理cluster,node, index 数据和元数据

3.通过index进行执行crud和搜索

4.执行高级搜索,分页,排序,过滤,脚本编写,聚合等

cluster health 

api

_cat

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
1475247709 17:01:49  elasticsearch green           1         1      0   0    0    0        0             0                  -                100.0%

由以上返回结果可见:

cluster name : elasticsearch(默认的集群名称)

node number:1

node data number: 1

shards: 0 (在shards里面没有数据)

status:green

集群健康状态

green

everything is good(集群功能齐全)

yellow

所有数据都是可用的但是一些副本可能还没分配(集群功能齐全)

red

出于某种原因,某些数据不可用(集群部分功能齐全)。此时集群将继续为来自可用shards的搜索请求提供服务,但最好急躁修复,因为存在未分配的shards。

列出所有索引

GET /_cat/indices?v

创建索引

创建一个customer的索引

// 创建名未customer得索引,pretty表明如果有响应,打印标准得json
PUT /customer?pretty

index/replace documents

给customer index里面添加数据

PUT /customer/_doc/1?pretty
{
  "name": "John Doe"
}

响应结果

{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

其实es并不需要在文档加入index之前显示创建index。当customer index不存在的时候,会自动创建index。

查询刚刚创建的文档

GET /customer/_doc/1?pretty

返回结果

{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 25,
  "_primary_term" : 1,
  "found" : true,
  "_source" : { "name": "John Doe" }
}

由返回结果可知:

found: true,表明找到了一个_id为1 的文档数据

_source:返回该文档的json格式数据

delete index

DELETE /customer?pretty

modify data

之前已经执行过

PUT /customer/_doc/1?pretty
{
  "name": "John Doe"
}

当再次执行上述命令,使用相同的id=1,但是name改变:

PUT /customer/_doc/1?pretty
{
  "name": "Jane Doe"
}

由于是相同的id, 那么最新的文档就会替换掉上次的结果。

当使用不同的id的时候,就会生成一个新的文档,并且原有的文档不会受任何影响。

PUT /customer/_doc/2?pretty
{
  "name": "Jane Doe"
}

执行以上命令会生成一个request _id为2 的文档,以前_id为1 的文档不会受到任何影响。

当在检索的时候,id部分是可选的,如果没有指定,会生成一个随机id,并且用作该文档的index id。

当没有明确指定id 的时候使用POST

POST /customer/_doc?pretty
{
  "name": "Jane Doe"
}

update documents

除了index/replace documents,也可以update documents。

当执行update的时候,会删除旧的文档,并给新的文档重新index。

将之前创建的索引customer。id=1的更新name:

POST /customer/_update/1?pretty
{
  "doc": { "name": "Jane Doe" }
}

在更新name的时候添加属性age:

POST /customer/_update/1?pretty
{
  "doc": { "name": "Jane Doe", "age": 20 }
}

update也可以执行脚本

POST /customer/_update/1?pretty
{
  "script" : "ctx._source.age += 5"
}

根据查询条件来更新

https://www.elastic.co/guide/en/elasticsearch/reference/7.1/docs-update-by-query.html

POST twitter/_update_by_query?conflicts=proceed

update documents

删除之前创建的id=2的文档

DELETE /customer/_doc/2?pretty

也可以根据查询条件来删除

https://www.elastic.co/guide/en/elasticsearch/reference/7.1/docs-delete-by-query.html

POST twitter/_delete_by_query
{
  "query": { 
    "match": {
      "message": "some message"
    }
  }
}

批量处理: _bulk

POST /customer/_bulk?pretty
{"update":{"_id":"1"}}
{"doc": { "name": "John Doe becomes Jane Doe" } }
{"delete":{"_id":"2"}}

上述命令更新_id=1的document,并且删除_id=2的document。

 

load simple dataset

准备数据account.json

{
    "account_number": 0,
    "balance": 16623,
    "firstname": "Bradshaw",
    "lastname": "Mckenzie",
    "age": 29,
    "gender": "F",
    "address": "244 Columbus Place",
    "employer": "Euron",
    "email": "bradshawmckenzie@euron.com",
    "city": "Hobucken",
    "state": "CO"
}

load 

curl -H "Content-Type: application/json" -XPOST "localhost:9200/bank/_bulk?pretty&refresh" --data-binary "@accounts.json"

search 

_search

search有两种方式

1.参数放在request uri后面

GET /bank/_search?q=*&sort=account_number:asc&pretty

q=*: 在索引中匹配所有的文档

sore=account)number:asc: 结果按照account_number升序

部分结果如下:

{
  "took" : 63,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
        "value": 1000,
        "relation": "eq"
    },
    "max_score" : null,
    "hits" : [ {
      "_index" : "bank",
      "_type" : "_doc",
      "_id" : "0",
      "sort": [0],
      "_score" : null,
      "_source" : {"account_number":0,"balance":16623,"firstname":"Bradshaw","lastname":"Mckenzie","age":29,"gender":"F","address":"244 Columbus Place","employer":"Euron","email":"bradshawmckenzie@euron.com","city":"Hobucken","state":"CO"}
    }, {
      "_index" : "bank",
      "_type" : "_doc",
      "_id" : "1",
      "sort": [1],
      "_score" : null,
      "_source" : {"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
    }, ...
    ]
  }
}

 took: es执行这个查询耗费的时间,单位毫秒

time_out:是否查询超时

_shards:告诉我们有多少个shards被查询,包括查询成功/失败的shards个数。

hits:查询结果

hits.total:包含了总的文档数量信息。由请求参数:track_total_hits控制,当track_total_hits=true,强制进行准确计数。

hits.total.value:总的命中的值

hits.total.relation:是否是hits.total.value的确切数量。eq:等于,gte:大于等于

hits.hits:实际查询的结果数组

hits.sort:结果的排序key,如果缺失,那就是以socre排序。

hits._score:是一个数值。是文档于指定的搜索查询匹配程度的相对独立。分数越高,文档越相关。当仅仅在filter 文档的时候才会产生_score。

2.参数在requrst body里面

GET /bank/_search
{
  "query": { "match_all": {} },
  "sort": [
    { "account_number": "asc" }
  ]
}

上述命令执行结果跟放在url后面的结果是一致的。

query dsl

dsl(domain specific language)

1.leaf query clauses

在指定的领域找指定的值。如match, term,  range。这些查询可用单独存在使用。

2.compound query clauses

封装了leaf query clauses或者compound query clause

 

查询指定索引里的所有文档

GET /bank/_search
{
  "query": { "match_all": {} }
}

如果size没有明确指定,则默认为10

GET /bank/_search
{
  "query": { "match_all": {} },
  "size": 1
}

查询第10-19条。如果from没有指定,则默认为0。size没有指定,则默认为10.

GET /bank/_search
{
  "query": { "match_all": {} },
  "from": 10,
  "size": 10
}

将结果按照order降序

GET /bank/_search
{
  "query": { "match_all": {} },
  "sort": { "balance": { "order": "desc" } }
}

excuting search

默认情况下,查询结果是完整的返回,如果不想要整个完整的document结果,可用指定某些字段来返回。

指定返回document里面的_source里面的account_number, balance字段

GET /bank/_search
{
  "query": { "match_all": {} },
  "_source": ["account_number", "balance"]
}

匹配查询

查询account_number=20的

GET /bank/_search
{
  "query": { "match": { "account_number": 20 } }
}

查询address包含mill的结果

GET /bank/_search
{
  "query": { "match": { "address": "mill" } }
}

查询address包含mill或者lane的文档

GET /bank/_search
{
  "query": { "match": { "address": "mill lane" } }
}

查询address包含“mill lane”这个短语的文档

GET /bank/_search
{
  "query": { "match_phrase": { "address": "mill lane" } }
}

bool 查询,must, should, must_not

查询address包含milllane的文档

GET /bank/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}

查询address包含nil或者lane的

GET /bank/_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}

查询address既不包含nill也不包含lane的文档

GET /bank/_search
{
  "query": {
    "bool": {
      "must_not": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}

查询age=40,并且state!=id的

GET /bank/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "age": "40" } }
      ],
      "must_not": [
        { "match": { "state": "ID" } }
      ]
    }
  }
}

executing filters

查询账户余额在20000-30000的结果

GET /bank/_search
{
  "query": {
    "bool": {
      "must": { "match_all": {} },
      "filter": {
        "range": {
          "balance": {
            "gte": 20000,
            "lte": 30000
          }
        }
      }
    }
  }
}

excuting aggregations

聚合。

提供了将数据分组和提取统计信息的功能。最简单的方式是sql的group by。

将所有账户按照state分组,返回前10条数据。

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      }
    }
  }
}

上述的size=0,代表不显示查询命中结果,因为只想看到聚合结果。

返回结果

{
  "took": 29,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped" : 0,
    "failed": 0
  },
  "hits" : {
     "total" : {
        "value": 1000,
        "relation": "eq"
     },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "group_by_state" : {
      "doc_count_error_upper_bound": 20,
      "sum_other_doc_count": 770,
      "buckets" : [ {
        "key" : "ID",
        "doc_count" : 27
      }, {
        "key" : "TX",
        "doc_count" : 27
      }, {
        "key" : "AL",
        "doc_count" : 25
      }, {
        "key" : "MD",
        "doc_count" : 25
      }, {
        "key" : "TN",
        "doc_count" : 23
      }, {
        "key" : "MA",
        "doc_count" : 21
      }, {
        "key" : "NC",
        "doc_count" : 21
      }, {
        "key" : "ND",
        "doc_count" : 21
      }, {
        "key" : "ME",
        "doc_count" : 20
      }, {
        "key" : "MO",
        "doc_count" : 20
      } ]
    }
  }
}

根据state计算每个账户的平均余额

(默认就是前10个, from=0, size=10)

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

按照state,将计算的平局余额降序

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword",
        "order": {
          "average_balance": "desc"
        }
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

先按照age分组(20-29,30-39,40-49),再按照性别分组,最后计算每个age,性别组里账户的平均余额

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_age": {
      "range": {
        "field": "age",
        "ranges": [
          {
            "from": 20,
            "to": 30
          },
          {
            "from": 30,
            "to": 40
          },
          {
            "from": 40,
            "to": 50
          }
        ]
      },
      "aggs": {
        "group_by_gender": {
          "terms": {
            "field": "gender.keyword"
          },
          "aggs": {
            "average_balance": {
              "avg": {
                "field": "balance"
              }
            }
          }
        }
      }
    }
  }
}

set up es

安装

 

配置

设置jvm.options

其实jvm.options没必要修改,如果需要可修改heap size .

jvm.options详解

空行,或者#开头(代表注释)的都会被忽略。

以-开头的,代表与jvm版本无关的选项

以数字:- 开头的,当且仅当数字与jvm版本匹配的时候才适用

如:  8:-Xmx2g

以数字-:- 当前仅当jvm版本大于等于该数字才生效

如: 8-:-Xmx2g

数字-数字:-, 当前仅当jvm版本再两个数字之间的才会生效

安全设置:elasticsearch-keystore

https://www.elastic.co/guide/en/elasticsearch/reference/7.1/secure-settings.html

创建keystore

bin/elasticsearch-keystore create

列出在keystore里面的所有设置

bin/elasticsearch-keystore list

新增字符串设置

bin/elasticsearch-keystore add the.setting.name.to.set

新增文件设置

bin/elasticsearch-keystore add-file the.setting.name.to.set /path/example-file.json

移除设置

bin/elasticsearch-keystore remove the.setting.name.to.remove

重新加载安全设置

在每个集群上会解密和重新读取整个keystore,但仅仅reloadable安全设置才会生效。其他的设置的更改将会在下次重启才生效

POST _nodes/reload_secure_settings

logging 配置

https://www.elastic.co/guide/en/elasticsearch/reference/7.1/logging.html

es使用log4j2来记录日志。配置文件为log4j2.properties

es暴露3个属性,可用在配置文件中使用,以确定日志未见得位置。

${sys:es.logs.base_path}将解析为日志目录

${sys:es.logs.cluster_name}将解析为群集名称(在默认配置中用作日志文件名的前缀)

${sys:es.logs.node_name}并将解析为节点名称(如果明确设置了节点名称)

如果日志目录path.logs为:/var/log/elasticsearch,集群名称为:production

那么${sys:es.logs.base_path}将被解析为: /var/log/elasticsearch

${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}.log 将被解析为:/var/log/elasticsearch/production.log.

审核安全设置

https://www.elastic.co/guide/en/elasticsearch/reference/7.1/auditing-settings.html

跨集群副本设置

https://www.elastic.co/guide/en/elasticsearch/reference/7.1/ccr-settings.html

es集群元素

 

搜索相关性排序算法

https://lanffy.github.io/2019/05/08/Elasticsearch-Search-Score-Algorithm

相关性

查询语句为每个文档生成一个_score字段。评分的计算方式取决于查询类型,不同查询语句用于不同的查询目的。

fuzzy: 计算与关键词的拼写相似度

terms: 计算找到的内容与关键词组成部分匹配的百分比。

但是通常所说的相关性指的是全文本字段值相对于全文本检索词的相似度的算法。

相似度算法:检索词频率/反向文档频率 TF/IDF

检索词频率

检索词在该字段出现的频率,出现频率越高,相关性越高。出现5次的相关性比出现1次的相关性高。

反向文档频率

每个检索词在索引中出现的频率。频率越高,相关性越低。检索词出现在多数文档中会比出现在少数文档中的权重更低。

字段长度准则

字段长度是多少?字段越长,相关性越低

TF-IDF

Term Frequency-Inverse Document Frequency。一种用来信息检索与文本挖掘的常用加权算法。是一种统计方法,用来评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。

TF(词频)

词频的所在对象是一个具体的文档,是指一个文档中出现某个单词(Term)的频率(Frequency)。用的是词频,而不是次数,访问文档内容过长而导致某些单词出现次数过多。

 

逆向文件频率

在文档集合中,包含某个单词的文档数量。表示一个单词在一个文档集合中的普遍重要程度。

 某一特定文件内的高词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的tf-idf。因此,tf-idf倾向于过滤掉常见的词语,保留重要的词语。

算法原理

TF-IDF实际是两个算法TF与IDF的乘积

  • TF表示的是一个单词在一段文本中的重要程度,随着单词的增加而增加
  • IDF表示的是一个单词在一个文档集合中的重要程度,越稀有权重越高,所以它随着单词的增加而降低

 TF-IDF算法例子

额外的学习资料

https://lanffy.github.io/2019/04/16/How-Elasticsearch-Create-Index

https://segmentfault.com/a/1190000019173237?utm_source=tag-newest

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值