乐趣区

关于elasticsearch:Elasticsearch操作实践手册建议收藏篇

我是啤酒就辣条。

但行好事,莫问前程。

官网为咱们提供了多种语言操作 Elasticsearch 的 API,能够很不便的在我的项目中操作。学习利用原生申请操作 Elasticsearch,不便保护数据库,还能放慢学习应用不同语言的 API。

本博客应用 kibana 发动申请,应用 kibana 能够查看快捷键。

索引操作

创立索引

创立索引应用 PUT 申请,前面跟上索引名称就好了,因为 7.x 默认 type 为_doc,所以前面不用跟上 type 了。在 PUT 简略申请同时,能够加上 JSON 申请体,进行简单创立。

PUT /user
{
  "settings": {
    "index": {
      "number_of_shards": 3,  
      "number_of_replicas": 2 
    }
  },
  "mappings": {
    "properties": {"name": { "type": "text"},
      "age": {"type": "short"},
      "city":{"type": "keyword"}
    }
  }
}

创立索引 user,能够通过参数setting 设置分片和正本数,通过 number_of_shards 设置一共有 3 个分片,通过 number_of_replicas 给每个分片设置 2 个正本,默认不指定的话,这两个参数都是 1。通过 mappings 规定文档各个 Filed 插入类型。此外,还能够设置 aliases 字段,给索引创立别名,这样不仅能够通过别名拜访该索引,还能够定义查问条件、指定查问分片等等,详情请参考。

删除索引

删除索引,应用 DELETE 申请。

DELETE /user

查看索引

查看索引,应用 GET 申请,能够查看索引设置的参数。

删除之后,我又从新增加索引,没有设置 settings,所以分片和正本都是 1。

你也能够通过在索引前面加参数来查看某一具体参数,如:

GET /user/_settings
GET /user/_mappings
GET /user/_aliases

批改索引局部设置

能够通过 PUT 申请批改局部索引的 settings,例如,分片正本数量能够批改,然而分片数量不能够通过这种形式批改。

PUT /user/_settings
{"number_of_replicas": 3}

能够通过以上申请,批改分片正本。

文档操作

创立好索引,来看下文档的增删改查,这是日常业务用的最多的中央。

插入文档

新增文档应用 PUTPOST 申请。

PUT /<target>/_doc/<_id>

POST /<target>/_doc/

PUT /<target>/_create/<_id>

POST /<target>/_create/<_id>

target为索引名称,_doc为默认 type。通过前两种申请可看出,id 能够自行指定,也能够由 ES 主动生成。_create能够保障只有当文档不存在的时候进行插入,而 _doc 还能够用于文档更新。

POST /user/_doc/1
{
  "name":"pjjlt",
  "age":26,
  "city":"sjz"
}

更新文档

更新文档能够应用 PUT 或者 POST 申请关键字,全量更新。

POST /user/_doc/1
{
  "name":"pjjlt",
  "age":3,
  "city":"sjz"
}

还能够通过 _update 命令部分更新,所谓部分更新,是讲申请体内不须要退出全副字段,只退出须要批改的字段就好,其余字段不变。全量更新会替换整个文档。

POST /user/_update/1
{
  "doc":{"age": 26}
}

此外还能够通过脚本批改,例如将所有存在 age 字段的文档,其值改成 5 岁。

POST /user/_update_by_query
{
  "script": {"source": "ctx._source['age']=5" 
  },
  "query": {
    "bool": {
      "must": [
        {
          "exists": {"field": "age"}
        }
      ]
    }
  }
}

此外 update_update_by_query字段还能够批改Filed,例如将 name 批改成 name1,这块内容应用较少,如感兴趣,请参考官网文档。

删除文档

删除文档能够应用 DELEETE 申请,删除指定 id 的文档,也能够应用_delete_by_query,删除指定条件下的文档。

DELETE /user/_doc/1
POST /user/_delete_by_query
{
  "query": {
    "match": {"name": "pjjlt"}
  }
}

查找文档

查找文档是 ES 操作最精彩的局部,这里只介绍简略的查问,简单查问、聚合查问前面会介绍。

依据 id 查问某文档。

GET /user/_doc/1

查找某索引下的全副文档

GET /user/_search?pretty

pretty参数在浏览器中才会发挥作用,格式化返回 json 的。以上这条命令默认返回 10 条数据,想返回更多数据能够增加 size 字段。

GET /user/_search?pretty&size=20

能够看出,数据局部在 hits 外面,Spring 提供的 elasticsearch 客户端会有对应的实体类,在我的项目中很不便的应用。上面看下这几局部的含意。

元素 含意
took 运行查问须要多长时间
time_out 申请是否超时
_shards 搜寻了多少分片,多少胜利
多少跳过,多少失败
hits.total 总共有多少数据
hits._max_score 查问到的文档中,关联度最大文档分数
hits.hits._source 查问到的数据
hits.hits.id 某文档的主键

批量操作

批量操作是指,一批命令同时执行(缩小 IO),这些命令不肯定是同种类型。

应用 _bulk 命令能够进行文档的批量增删改。

POST _bulk
{"update" : { "_index" : "user", "_id" : "1"} }
{"doc" : {"age" : 18} }
{"create" : { "_index" : "user", "_id" : "2"} }
{"name" : "小明","age":32,"city":"beijing"}
{"create" : { "_index" : "user", "_id" : "3"} }
{"name" : "小红","age":21,"city":"sjz"}
{"create" : { "_index" : "user", "_id" : "4"} }
{"name" : "mark","age":22,"city":"tianjin"}
{"delete" : { "_index" : "user", "_id" : "4"} }

以上命令更新了 id 为 1 文档的年龄,新增 id 为 2、3、4 的文档,再删除 id 为 4 的文档。

上边的命令堆在一起不不便看,上面独自写看,不便读者查看。

批量新增

POST _bulk
{"create" : { "_index" : "user", "_id" : "2"} }
{"name" : "小明","age":32,"city":"beijing"}
{"create" : { "_index" : "user", "_id" : "3"} }
{"name" : "小红","age":21,"city":"sjz"}

{"index" : { "_index" : "user", "_id" : "4"} }
{"name" : "mark","age":22,"city":"tianjin"}

create命令是只有文档不存在,才会插入,index会判断如果存在就更新,不存在就插入。

批量更新

POST _bulk
{"update" : { "_index" : "user", "_id" : "1"} }
{"doc" : {"age" : 18} }
{"update" : { "_index" : "user", "_id" : "2"} }
{"doc" : {"age" : 20} }

和新增一样,update命令下一行须要紧跟这 data 数据。

批量删除

POST _bulk
{"delete" : { "_index" : "user", "_id" : "3"} }
{"delete" : { "_index" : "user", "_id" : "4"} }

批量查找

批量查找,应用 _mget 关键字,批量查找如果不逾越索引,也具备简写模式。

GET /_mget
{
  "docs": [
    {
      "_index": "user",
      "_id": "1"
    },
    {
      "_index": "user",
      "_id": "2"
    }
  ]
}

# 还能够简写模式
POST /user/_mget
{
  "ids": [
    "1",
    "2",
    "3"
  ]
}

DSL 查问

Elasticsearch 提供了一个残缺的基于 JSON 的查问 DSL(畛域特定语言)来定义查问。能够将查问 DSL 看作查问的 AST(形象语法树),它由两种类型的子句组成:Leaf query clauses(叶查问子句)和Compound query clauses(复合查问子句)

以上摘自官网,简略来说,DSL 就是将查问条件放到 JSON 中,进行查问。

Leaf query clauses在特定字段上查找特定的值,例如 matchtermrange 查问等等。

Compound query clauses将叶查问子句和其余合乎查问子句联合起来,例如 bool 查问等等。

match

match 是一个规范查问,当查问一个文本的时候,会先将文本分词。当查问确切值的时候,会搜寻给定的值,例如数字、日期、布尔或者被 not_analyzed 的字符串。

GET /user/_search
{
  "query": {
    "match": {"name":"小明"}
  }
}

下面的操作会先将“小明”分词为“小”、“明”(当然具体还要看你的分词器),而后再去所有文档中查找与之相匹配的文档,并依据关联度排序返回。

match_phrase

match_phrase 会保留空格,match 会把空格疏忽。

GET /user/_search
{
  "query": {
    "match_phrase": {"name":"小 明"}
  }
}

留神,分词是空格会给前一个元素,比方下面的字符串分子之后是,“小”,“明”。

multi_match

多字段查问,一个查问条件,看所有多个字段是否有与之匹配的字段。前面咱们也能够应用 should 更加灵便。

GET /user/_search
{
  "query": {
    "multi_match": {
      "query":    "哈哈", 
      "fields": ["name","city"] 
    }
  }
}

match_all

匹配所有,并可设置这些文档的 _score,默认_score 为 1,辣条君认为这里没有计算_score,所以速度会快很多。

GET /user/_search
{
  "query": {"match_all": { "boost" : 1.2}
  }
}

boost参数能够省略,默认是 1。

term

term 是一种齐全匹配,次要用于准确查找,例如数字、ID、邮件地址等。

GET /user/_search
{
  "query": {
    "term": {"age": 18}
  }
}

terms

terms 是 term 多条件查问,参数能够传递多个,以数组的模式示意。

GET /user/_search
{
  "query": {
    "terms": {"age":[18,21]
    }
  }
}

wildcard

通配符,看示例容易了解,通配符能够解决分词匹配不到的问题,例如 ’haha’ 能够通过 ’*a’ 匹配。

GET /user/_search
{
  "query": {
    "wildcard": {"name":"*a"}
  }
}

exists

查看某文档是否有某属性,返回蕴含这个 Filed 的文档。

GET /user/_search
{
  "query": {
    "exists": {"field": "name"}
  }
}

fuzzy

返回与查问条件雷同或者类似的匹配内容。

GET /user/_search
{
  "query": {
    "fuzzy": {"name":"mjjlt"}
  }
}

搜寻条件是 mjjlt,能够搜进去 name 为pjjlt 的文档。这个操作是不是在百度的时候常常见到呢?

ids

多 id 查问,这个 id 是主键 id,即你规定或者主动生成那个。

GET /user/_search
{
  "query": {
    "ids": {"values":[1,2,3]
    }
  }
}

prefix

前缀匹配

GET /user/_search
{
  "query": {
    "prefix": {"name":"pj"}
  }
}

range

范畴匹配。参数能够是 gt(大于)、gte(大于等于)、lt(小于)、lte(小于等于)

GET /user/_search
{
  "query": {
    "range": {
      "age":{
          "gt":1,
          "lt":30
      }
    }
  }
}

regexp

正则匹配。value 是正则表达式,flags 是匹配格局,默认是 ALL,开启所有。更多格局请戳

GET /user/_search
{
  "query": {
    "regexp": {
      "name":{
          "value": "p.*t",
          "flags": "ALL"
      }
    }
  }
}

bool

bool 能够用来组合其余子查问。其中常蕴含的子查问蕴含:must、filter、should、must_not

must

must外部的条件必须蕴含,外部条件是 and 的关系。如查看所有 name 中蕴含“小”并且 age 是 32 的用户文档。

GET /user/_search
{
  "query": {
    "bool" : {
      "must": [{"term" : { "name" : "小"}},
        {"term" : { "age" : 32}}
      ]
    }
  }
}

filter

filter是文档通过一些条件过滤下,这是四个关键词中惟一 和关联度无关的,不会计算_score,常常应用的过滤器会产生缓存。

GET /user/_search
{
  "query": {
    "bool" : {
      "filter": {"term" : { "name" : "小"}
      }
    }
  }
}

比照两张图能够看出,filter 并没有计算_score,搜寻速度较快。

must_not

这个和 must 相同,文档某字段中肯定不能蕴含某个值,相当于“非”。

should

should能够看做 or 的关系,例如上面查问 name 蕴含 ” 小 ” 或者年龄是 18 岁的用户。

GET /user/_search
{
  "query": {
    "bool" : {
      "should": [{"term" : { "name" : "小"}},
        {"term" : { "age" : 18}}
      ]
    }
  }
}

聚合查问

Elasticsearch 除全文检索性能外提供的针对 Elasticsearch 数据做统计分析的性能。能够查问某组数据的最大最小值,分组 查问某些数据。

  • Metric(指标): 指标剖析类型,如计算最大值、最小值、平均值等等(对桶内的文档进行聚合剖析的操作)
  • Bucket(桶): 分桶类型,相似 SQL 中的 GROUP BY 语法(满足特定条件的文档的汇合)
  • Pipeline(管道): 管道剖析类型,基于上一级的聚合剖析后果进行在剖析

Metric(指标)数据

罕用数学操作

这里罕用的数学操作有min(最小)、max(最大)、sum(和)、avg(平均数)。留神这些操作只能输入一个剖析后果。应用形式大同小异。

GET /user/_search
{
    "aggs" : {
        "avg_user_age" : 
        {"avg" : { "field" : "age"} 
        }
    }
}

以上示例查问所有用户的平均年龄,返回所有文档和聚合查问后果。aggs是聚合查问关键词,avg_user_age是查问名称,用户能够自行定义。

cardinality

计算某字段去重后的数量

GET /user/_search
{
    "aggs" : {
        "avg_user" : 
        {"cardinality" : { "field" : "age"} 
        }
    }
}

能够计算,所有文档中年龄不雷同的文档个数。

percentiles

对指定字段的值按从小到大累计每个值对应的文档数的占比,返回指定占比比例对应的值。

默认统计百分比为[1, 5, 25, 50, 75, 95, 99]

GET /user/_search
{
    "aggs" : {
        "avg_user" : 
        {"percentiles": { "field" : "age"} 
        }
    }
}

# 返回值(省略文档局部,只剖析后果局部)
  "aggregations" : {
    "avg_user" : {
      "values" : {
        "1.0" : 12.0,
        "5.0" : 12.0,
        "25.0" : 20.25,
        "50.0" : 29.0,
        "75.0" : 57.75,
        "95.0" : 123.0,
        "99.0" : 123.0
      }
    }
  }

能够看出,前 1% 的用户小于 12 岁,5% 的用户小于 12 岁,25% 的用户小于 20.25 岁,50% 的用户小于 29 岁。。。

percentile_ranks

percentiles 是通过百分比求出文档某字段,percentile_ranks 是给定文档中的某字段求百分比。

GET /user/_search
{
    "aggs" : {
        "avg_user" : 
        { 
          "percentile_ranks": 
            { 
              "field" : "age",
              "values" : [18, 30]
            } 
        }
    }
}

# 返回值(省略文档局部,只剖析后果局部)
  "aggregations" : {
    "avg_user" : {
      "values" : {
        "18.0" : 18.51851851851852,
        "30.0" : 54.44444444444445
      }
    }
  }

能够看出,小于等于 18 岁的用户有 18.52%,小于等于 30 岁的用户有 54.4%。

top_hits

top_hits 能够失去某条件下 top n 的文档。

GET /user/_search
{
  "aggs": {
    "avg_user" : {
      "top_hits": {
          "sort": [
          {
            "age": {"order": "asc"}
          }
        ],
        "size": 1
      }
    }
  },
  "size": 0
}

取年龄最小的那一个。

Bucket(桶)

相似于分组的概念。

terms

依据给定的 filed 分组,返回每组多少文档。

GET /user/_search
{
    "aggs" : {
        "avg_user" : 
        { 
          "terms": {"field": "city"}
        }
    }
}

以上依据城市分组,看每个城市有多少用户。

ranges

依据区间分组

GET /user/_search
{
  "aggs": {
    "price_ranges": {
      "range": {
        "field": "age",
        "ranges": [{ "to": 20},
          {"from": 20, "to": 30},
          {"from": 30}
        ]
      }
    }
  }
}

能够查看每个年龄层的用户数量。

还有些很乏味的指令,例如 [IP range] 能够依据 ip 段区间分组,当前用到再说吧,心愿文本能够不段更新的说 …

退出移动版