es版本发布相当快,从1.x到2.x,再直接到5.x,6.x
索引这个词在es中有多重意思:
索引(名词):一个索引类似于传统数据库中的一个索引,用于存储关系型文档。索引的复数为indexes或indices。
索引(动词):索引一个文档就是存储一个文档到一个索引(名词)中以便它可以被检索和查询到,相当于SQL中的upsert。
倒排索引:关系型数据库通过增加一个索引比如B-tree索引到指定列上,以便提升数据检索速度。es使用了一个叫做倒排索引的结构来达到相同的目的。默认的,一个文档中的每一个属性都是被索引的(有一个倒排索引的)和可搜索的。一个没有倒排索引的属性是不能被搜索到的。
es是利用分片将数据分发到集群各处的。分片是数据的容器,文档保存在分片内,分片又被分配到集群内的各个节点里。当集群规模扩大或者缩小时,es会自动在各节点中迁移分片,使得数据依然均匀分布在集群里。一个分片可以是主分片或者副本分片。副本分片是主分片的拷贝。技术上说,一个主分片最多能够存储Integer.MAX_VALUE - 128个文档。在索引建立的时候就已经确定了主分片数(number_of_shards,默认5个主分片),不能改,但是副本分片数(number_of_replicas)可以随时修改。
在es中每个文档都有一个版本号,当每次对文档进行修改时(包括删除),_version 的值都会递增。
本次学习的是es6.3.1版本,看的是6.3版本的官方文档。部门用的是5.6.3
添加索引:
put /website
{
"settings":{
"number_of_shards":3,
"number_of_replicas":1
}
}
更改索引的副本数:
put /website/_settings
{
"settings":{
"number_of_replicas":0
}
}
查看某index的alias:
get /${index}/_alias
如 get /posts/_alias
往某索引添加数据,指定id,put、post都可以:
put /website/blog/1
{
"id":"1",
"name":"zhangsan"
}
往某索引添加数据,不指定id,只能用post:
post /website/blog
{
"name":"lisi",
"password":"lisi"
}
返回文档的一部分:
get /website/blog/1?_source=id,name
只返回_source数据,不要_index、_type、_id等元数据:
get /website/blog/1/_source
更新整个文档,再次put该文档即可:
put /website/blog/1
{
"password":"lisi",
"city":"henan"
}
在es中文档是不可改变的,不能修改它们,只能替换。id=1的文档,原本数据是{"id":"1","name":"zhangsan"},现在变成了{"password":"lisi","city":"henan"},新数据和之前数据一点关系都没有。
在内部,es将旧文档标记为已删除,并增加一个全新的文档。尽管不能再对旧版本文档进行访问,但它并不会立即消失,当继续索引更多数据时,es会在后台清理这些已删除的文档。
部分更新文档。将接收到的文档与现有文档合并,覆盖现有字段,增加新字段:
有doc和script两种方式
doc方式:
post /website/blog/1/_update
{
"doc":{
"password":"abc123",
"title":"woshititle"
}
}
此时id=1的文档数据为
{
"password": "abc123",
"city": "henan",
"title": "woshititle"
}
script方式:
post /website/blog/1/_update
{
"script": {
"source": "ctx._source.title='haizeiwang';ctx._source.birthday='1993/04/25';"
}
}
此时id=1的文档数据为
{
"password": "abc123",
"city": "henan",
"title": "haizeiwang",
"birthday": "1993/04/25"
}
一次取回多个文档,用_mget。既可以一次从单个索引中取多个文档,也可以一次从多个索引中取多个文档。即使某一个文档不存在,也不会报错:
一次从单个索引中取多个文档:
get /website/blog/_mget
{
"docs": [{
"_id": 1
},{
"_id": 123
},{
"_id": 1234
}]
}
_id指定文档的id。也可以省略docs数组,用ids数组,如下
get /website/blog/_mget
{
"ids": [1,123,1234]
}
一次从多个索引中取多个文档:因为多个文档在多个索引中,所以需要指定每个文档所属的索引
get /_mget
{
"docs": [{
"_index": "website",
"_type": "blog",
"_id": 1
},{
"_index": "spark",
"_type": "index",
"_id": 1
}]
}
如上,docs 数组包含要返回的多个文档信息,主要是用于指定index的_index、用于指定type的_type、用于指定id的_id。
批量操作,用_bulk。允许在单次请求中依次执行多个index、update、delete操作:
post _bulk
{"index":{"_index":"spark","_type":"index","_id" :"2"}}
{"name":"nimabi"}
{"index":{"_index":"spark","_type":"index","_id":"3"}}
{"age":"18"}
{"update":{"_index":"spark","_type":"index","_id":"2"}}
{"doc":{"age":"25"}}
{"delete":{"_index":"spark","_type":"index","_id":"3"}}
多索引查询:
在所有索引中搜索:get /_search
在spark索引中搜索:get /spark/_search
在spark索引中搜索index类型:get /spark/index/_search
在spark和website索引中搜索:get /spark,website/_search
在以s开头的索引中搜索:get /s*/_search
在spark和website索引中搜索index和blog类型:get /spark,website/index,blog/_search
在所有索引中搜索index和blog类型:get /_all/index,blog/_search
分页:
get /website/blog/_search?q=*&sort=account_number:asc,balance:desc&from=100&size=10
text和keyword的区别:
text和keyword都表示字符串类型(从5.x版本开始,废弃了string类型,拆分为text和keyword)
text 类型的值会被分词器分词(默认分词器是standard,中文的话需要引入ik分词器或者结巴分词器),并放入倒排索引。不能用于排序、聚合(即根据此字段排序会报错),除非显式指定 fielddata=true
keyword类型的值不会被分词器分词,可用于排序、聚合
某字符串值已经post进某index某type,如何查看分词情况:
get /${index}/${type}/${id}/_termvectors?fields=${fields_name}
如 get /posts/doc/1/_termvectors?fields=message,其中posts是index,doc是type,1是id,message是对应的字段名
某字符串会被某分词器处理成什么样子:
post /_analyze
{
"analyzer": "ik_max_word",
"text": "我是需要测试的字符串"
}
其中analyzer的值是要使用的分词器,text值是要测试的字符串。