Elasticsearch API

1.文档与索引

常见术语说明
文档 Document用户存储在 ES 中的数据文档,ES 中存储的最小单元,类比数据库表中的一行数据
索引 Index由具有相同字段的文档列表组成,类比数据库一张表(table)
节点 Node一个 ES 的运行实例,是集群的构成单元
集群 Cluster由一个或多个节点组成,对外提供服务

1、文档Document
Document 在 ES 中实际就是一个 Json Object,由字段(Field)组成,常见的数据类型如下:

-数据类型
字符串text(会分词)、keyword(不分词,直接将输入作为一个单词输出)
数值型long、integer、double、float,比较节省空间的字段有 half_float、scaled_float、short、byte
布尔boolean
日期date
二进制binary
范围类型integer_range、float_range、long_range、double_range、date_range
复杂数据类型array(数组类型)、object(对象类型,可以有自己的子字段)、nested object(嵌套类型)
地理位置数据类型geo_point、geo_shape
专用类型ip(记录ip地址)、completion(实现自动补全)、token_count(记录分词数)、murmur3(记录字符串hash值)、percolator、join

每一个 Document 都有唯一的 id 标识(可以自行指定或者 ES 自动生成)。每一个 Document 都有 MetaData(元数据),用于标注 Document 的相关信息:

元数据说明
_index文档所在的索引名
_type文档所在的类型名
_id文档唯一 id
_uid组合 id,由 _type 和 _id 组成(6.x 开始的版本不再起作用,同 _id 一样)
_source存储了文档的原始 Json 数据,可以从这里获取每个字段的内容
_all整合所有字段内容到该字段,默认禁用,也不推荐使用

2、索引Index

Index 中存储具有相同结构的 Document,每个 Index 都有自己的 mapping 定义,用于定义字段名和类型。

一个集群可以有多个 Index,比如:
nginx 日志存储的时候可以按照日期每天生成一个索引来存储

nginx-log-2018-01-01
nginx-log-2018-01-02
nginx-log-2018-01-03

2.Elasticsearch API

Elasticsearch 对外提供 RESTFul API :

Http Method:GET/POST/PUT/DELETE
URL基本格式:http://<ip>:<port>/<索引名>/<类型>/<文档id>

常用的两种交互方式:Curl 命令行,Kibana DevTools,这里我们使用 Kibana DevTools,以下命令全部基于 Kibana DevTools 书写,DevTools 中多个命令换一行即可同窗口展示运行。

1.分词API

ES 自带的分词器有:

分词器analyzer 参数特性
Standard Analyzer (默认分词器)standard按词切分,支持多语言,小写处理
Simple Analyzersimple按字母切分,小写处理
Whitespace Analyzerwhitespace按空格切分
Stop Analyzerstopstop word 指语气助词等修饰性的词语,比如 the、an、的、这 等,stop 相比 simple 多了 Stop Word 处理
Keyword Analyzerkeyword不分词,直接将输入作为一个单词输出
Pattern Analyzerpattern通过正则表达式自定义分隔符,默认是 \W+ 即非字词的符号作为分隔符
Language Analyzerlanguage提供了 30+ 常见语言的分词器

中文分词器推荐 IK:

分词器analyzer 参数特性
IK Analyzerik_max_word细粒度
ik_smart粗粒度

1、直接指定 analyzer 进行测试

POST /_analyze
{
  "analyzer":"standard",                  //分词器
  "text":"Elasticsearch是最流行的搜索引擎"   //测试文本
}

ES 返回参数:

{
  "tokens" : [
    {
      "token" : "elasticsearch",         //分词结果
      "start_offset" : 0,                //起始偏移
      "end_offset" : 13,                 //结束偏移
      "type" : "<ALPHANUM>",
      "position" : 0                     //分词位置
    },
    ...
}

2、直接指定索引中的字段进行测试:POST /<索引名>/_analyze

POST /book/_analyze
{
  "analyzer":"standard",
  "text":"Elasticsearch是最流行的搜索引擎"
}

3、可以自定义分词器进行测试

POST /_analyze
{
  "analyzer":"standard",
  "filter":["lowercase"],         //自定义analyzer, lowercase:小写
  "text":"Elasticsearch是最流行的搜索引擎"
}

2.索引API
1.创建索引

1、创建索引请求:PUT /<索引名>

PUT /book

创建结构化索引:

PUT /book
{
	"settings": {
		"number_of_shards": "3",
		"number_of_replicas": "1"
	},
	"mappings": {
		"doc": {
		    "dynamic":false,  //通过dynamic参数来控制字段的新增, true:(默认)允许新增字段, false:不允许新增字段(但文档可以正常写入, 就是无法对字段进行查询等操作), strict:文档不能写入
			"properties": {
				"title": {"type": "text","index":true},  //index字段是控制当前字段是否索引, 默认true:记录索引, false:不记录索引, 即不可搜索
				"desc": {"type": "text"},
				"author": {"type": "text"},
				"country": {"type": "keyword"},          //keyword是不分词的一个字符串类型
				"word_count": {"type": "integer"},
				"date": {"type": "date", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"}
			}
		}
	}
}

2.自定义mapping

mapping 类似数据库中的表结构,主要作用:

  • 定义索引下的字段名(Field Name)
  • 定义字段的类型(比如 integer、text、keyword 等)
  • 定义倒排索引相关的配置(比如是否索引、记录 position等)

properties 下字段还可以通过以下选项自定义字段:

选项说明
type类型
index控制当前字段是否索引, 默认true:记录索引, false:不记录索引, 即不可搜索
index_options用于控制倒排索引记录的内容, 有4种配置: docs:只记录文档id, freqs:记录文档id和term frequencies, position:记录文档id、term frequencies和term position, offsets:记录文档id、term frequencies、term position和character offsets。text 类型默认配置为 positions,其他默认为docs。记录内容越多,占用空间越大。
null_value当字段遇到null值时的处理策略, 默认为null, 即空值, 此时ES会忽略该值, 可以通过设定该值设定字段的默认值。

查询 mapping:PUT /<索引名>/_mapping

GET /book/_mapping

mapping 中的字段类型一旦设定后,禁止直接修改,因为 Lucene 实现的倒排索引生成后不允许修改。如果要修改的话,需要重新建立新的索引,然后做 reindex 操作。

multi-fields(多字段特性):允许对同一个字段采用不同的配置,比如分词,常见例子如对人名实现拼音搜索,只需要在人名中新增一个子字段为 pinyin 即可:

{
    "mappings":{
        "doc":{
            "properties":{
                "title":{
                    "type":"text",
                    "fields":{
                        "type":"text",
                        "analyzer":"pinyin"
                    }
                }
            }
        }
    }
}

dynamic template(动态模板):允许根据 ES 自动识别的数据类型、字段名等来动态设定字段类型,可以实现效果如下:

  • 所有字符串类型都设定为keyword类型,即默认不分词
  • 所有以message开头的字段都设定为text类型,即分词
  • 所有以long_开头的字段都设定为long类型
  • 多有自动匹配为double类型的都设定为float类似,以节省空间
{
    "mappings":{
        "doc":{
            "dynamic_templates":[     //数组, 可指定多个匹配规则
                {
                    "strings_as_keywords":{       //template名称, 字符串默认使用keyword类型的模板
                        "match_mapping_type":"string", //匹配规则
                        "mapping":{"type":"keyword"}   //设置mapping信息
                    }
                },
                {
                    "message_as_text":{           //以message开头的字段都设置为text
                        "match_mapping_type":"string",
                        "match":"message*",
                        "mapping":{"type":"text"}
                    }
                },
                {
                    "double_as_float":{           //double类型设定为float,节省空间
                        "match_mapping_type":"double",
                        "mapping":{"type":"float"}
                    }
                }
            ],
            "properties":{}
        }
    }
}

匹配规则一般有如下几个参数:

匹配规则说明
match_mapping_typeES自动识别的字段类型,如boolean、long、string等
match、unmatch匹配字段名
path_match、path_unmatch匹配路径

自定义 mapping 的操作建议:

  1. 写入一条文档到 ES 的临时索引中,获取 ES 自动生成的 mapping
  2. 修改步骤 1 得到的 mapping,自定义相关配置
  3. 使用步骤 2 的 mapping 创建实际所需索引
3.索引模板

索引模板(Index Template)主要用于在新建索引时自动应用预先设定的配置,简化索引创建的操作步骤:

  • 可以设定索引的配置和 mapping
  • 可以有多个模板,根据 order 设置,order 大的覆盖小的配置

创建索引模板请求:PUT _template/<template名称>

PUT _template/test_template

PUT _template/test_template
{
    "index_patterns":["test*", "bar*"],    //匹配的索引名称
    "order":0,                             //order顺序配置
    "settings":{"number_of_shards":1},     //索引的配置
    "mappings":{
        "doc":{
            "_source":{
                "enabled":false
            },
            "properties":{
                "name":{
                    "type":"keyword"
                }
            }
        }
    }
}

创建索引模板后,再创建索引的时候,如果匹配上索引模板,则会直接应用这个模板的配置。

删除、查询索引模板请求:

DELETE _template/test_template

GET _template

GET _template/test_template

4.删除索引

删除索引请求:DELETE /<索引名>

DELETE /book

5.修改索引

修改索引 mappings 请求:POST /<索引名>/<类型>/_mappings

POST /book/doc/_mappings
{
	"properties": {
		"desc1": {"type": "text"}
	}
}

6.查询索引

查询索引请求:GET /<索引名>

GET /book

查询所有索引:

GET /_cat/indices?v

除了使用 Kibana DevTools 输入命令查询外,我们还可以通过 Kibana Management 可视化查询所有索引数据。

3.文档API

1.创建文档

1、指定文档 id 插入请求:PUT /<索引名>/<类型>/<文档id>

这里这个 <类型> 默认用 doc 就可以了,因为在 ES 高级版本中会直接把 <类型> 给干掉,这个 <类型> 没必要花太多时间去理解了。

PUT /book/doc/100001
{
	"title": "《细说Elasticsearch》",
	"desc": "使用ES",
	"author": "Tom",
	"country": "China",
	"word_count": 20000,
	"date": "2018-01-01"
}

创建文档时,如果索引不存在,ES 会自动创建对应的 索引 和 类型,ES 返回参数:

{
  "_index" : "book",         //索引名
  "_type" : "doc",           //类型
  "_id" : "100001",          //文档唯一id
  "_version" : 1,            //文档版本,更新文档时都会更新version,乐观锁的机制
  "result" : "created",      //执行结果
  "_shards" : {              //
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 23,
  "_primary_term" : 1
}

mapping 中未预先定义字段的情况下,ES 可以自动识别文档字段类型,从而降低用户使用成本。ES 是依靠 Json 文档的字段类型来实现自动识别字段类型,支持的类型如下:

Json类型ES类型
null忽略
booleanboolean
浮点类型float(非double是因为float比较省空间)
整数long
objectobject
array由第一个非null值得类型决定
string匹配为日期则设为date类型(默认开启),匹配为数字则设为float或long类型(默认关闭),当匹配都不符合时,设为 text 类型,并附带keyword的子字段

2、自动生成文档 id 插入请求(不推荐用这种,这种文档 id 不可控):POST/<索引名>/<类型>

POST /book/doc
{
	"title": "《细说Kibana》",
	"desc": "使用Kibana控制台",
	"author": "Bob",
	"country": "China",
	"word_count": 10000,
	"date": "2018-06-01"
}

3、批量创建文档(ES 允许一次创建多个文档,从而减少网络传输开销,提升写入速率):

POST _bulk
{"index":{"_index":"book","_type":"doc","_id":"100020"}}
{"title":"《细说JVM》","desc":"深入JVM","author":"Tom","country":"China","word_count":20000,"date":"2018-01-02"}
{"index":{"_index":"book","_type":"doc","_id":"100021"}}
{"title":"《细说JVM2》","desc":"深入JVM2","author":"Tom","country":"China","word_count":20000,"date":"2018-02-02"}
{"delete":{"_index":"book","_type":"doc","_id":"100005"}}
{"update":{"_index":"book","_type":"doc","_id":"100001"}}
{"doc":{"author":"Joy"}}

注意:每条数据第一行为索引名、类型和文档id,第二行为数据内容(共两行,不能分开写,否则无法解析,除 delete(删除)只有一句之外。

2.删除文档

文档删除请求:DELETE /<索引名>/<类型>/<文档id>

DELETE /book/doc/100001

3.修改文档

文档修改请求:POST /<索引名>/<类型>/<文档id>/<动作>

POST /book/doc/100001/_update
{
	"doc" : {"author": "Tony"}
}

4.文档查询API
1.根据文档id查询

根据文档id查询请求:GET /<索引名>/<类型>/<文档id>

GET /book/doc/100001

批量查询文档:

GET /_mget
{
    "docs":[
        {
            "_index":"book", "_type":"doc", "_id":"100001"
        },
        {
            "_index":"book", "_type":"doc", "_id":"100002"
        }
    ]
}

2.字段类查询-全文匹配
字段类查询说明
全文匹配针对 text 类型的字段进行全文检索,会对查询语句先进行分词处理,如 match、match_phrase 等 query 类型
单词匹配不会对查询语句做分词处理,直接去匹配字段的倒排索引,如 term、terms、range 等 query 类型

查询请求:POST /<索引名>/_search

<索引名> 可以为一个或多个(POST /book,book2/_search),多个用英文逗号隔开,也可以使用通配符(POST /bo*/_search)。

1、Match Query

简单匹配查询:

POST /book/_search
{
    "profile":true,   //可选参数, 返回所有分片的详细信息, 供用户检查查询执行时间和其他详细信息
	"query":{
		"match": {"title": "细说kibana"}
	}
}

ES 返回参数:

{
  "took" : 2,                    //查询耗时,单位ms
  "timed_out" : false,
  "_shards" : {
    "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0
  },
  "hits" : {                     //命中的文档数据
    "total" : 1,                 //符合条件的总文档数
    "max_score" : 1.0,
    "hits" : [                   //返回的文档详情数据数组,默认前10个文档
      {                          //每一个Json Object都是一个文档
        "_index" : "book",       //索引名
        "_type" : "doc",
        "_id" : "100001",        //文档唯一id
        "_score" : 1.0,          //文档相关性得分
        "_source" : {            //文档详情,原始Json数据
          "title" : "《细说Elasticsearch》",
          "desc" : "使用kibana", "author" : "Tom", "country" : "China",
          "word_count" : 20000, "date" : "2018-01-01"
        }}]
  }
}

我们还可以通过增加一些参数来控制筛选的结果:

POST /book/_search
{
    "profile":true,
	"query":{
		"match": {
		    "title":{
		        "query":"细说kibana",
		        "operator":"or"       //控制单词间的匹配关系, 可选项为or和and, 默认or
		        "minimum_should_match":"2"  //控制需要匹配的单词数
		    }
		}
	},
	"sort": [                        //排序
		{"date.keyword": "desc"},    //按日期倒排(如果是text类型需要加.keyword, keyword类型直接写字段名即可)
		{"_score": "desc"} ,         //日期相同则按得分倒排
		{"_doc": "desc"}             //得分相同则按文档内部id倒排
	],
	"from": 0,                       //from/size是最常用的分页方案, "from"表示开始位置, "size"表示大小
	"size": 10
}

2、Match All Query

查询某索引下所有文档:

POST /book/_search
{
	"query":{
		"match_all": {}
	},
	"from": 0,
	"size": 10
}

3、Match Phrase Query

短语匹配,对字段作检索, 有顺序要求:

POST /book/_search
{
    "profile":true,
	"query":{
		"match_phrase": {"title": "hello kibana"}
	}
}

我们还可以通过增加一些参数来控制筛选的结果:

POST /book/_search
{
    "profile":true,
	"query":{
		"match": {
		    "title":{
		        "query":"hello kibana",
		        "slop":"1"  //控制单词间的间隔, 比如设置为1则hello kibana和hello es kibana都会返回
		    }
		}
	}
}

4、Query String Query

多个字段的语法查询(查询包含 “Elasticsearch” 和 “细说”,或者是 Tom 写的书):

POST /book/_search
{
	"query":{
		"query_string": {
		    "fields":["title", "desc"],
			"query": "(Elasticsearch AND 细说) OR Tom"
		}
	}
}

5、Simple Query String Query

类似 Query String Query,但是会忽略错误的查询语法,并且仅支持部分查询语法,常用的逻辑符号有+ 代指 AND、| 代指 OR、- 代指 NOT,不能使用 AND、OR、NOT 等关键词:

POST /book/_search
{
	"query":{
		"simple_query_string": {
		    "fields":["title", "desc"],
			"query": "(Elasticsearch + 细说) | Tom"
		}
	}
}

3.字段类查询-单词匹配

将查询语句作为整个单词进行查询,即不对查询语句做分词处理。查询请求:POST /<索引名>/_search

1、Term Query /Terms Query

具体项查询(查询所有字数为 10000 的书):

POST /book/_search
{
	"query":{
		"term": {
			"word_count": 10000
		}
	}
}

Terms Query允许一次传入多个单词进行查询:

POST /book/_search
{
	"query":{
		"terms": {
			"word_count": [10000, 20000]
		}
	}
}

3、Range Query

范围查询,主要针对数值和日期类型。

查询字数在10000-20000的书, gte代表大于等于, gt代表小于, lte代表小于等于):

POST /book/_search
{
	"query":{
		"range": {
			"word_count": {"gte": 10000, "lte": 20000}
		}
	}
}

查询出版时间大于等于2018-01-01的书:

POST /book/_search
{
	"query":{
		"range": {
			"date": {"gte": "2018-01-01"}
		}
	}
}

相对时间查询(+1h表示加一个小时, -1d表示减一天, /d表示将时间舍入到天,包括 y-years m-months w-weeks d-days h-hours m-minutes s-seconds 等,假设now=2018-01-02 12:00:00 now+1h=2018-01-02 13:00:00 now-1h/d=2018-01-02 00:00:00 2016-01-01||+1M/d=2016-02-01 00:00:00):

POST /book/_search
{
	"query":{
		"range": {
			"date": {"gte": "now-20y"}
		}
	}
}

3.复合查询

复合查询是指包含字段类查询或复合查询的类型,主要包括:constant_score query、bool query、dis_max query、function_score query、boosting query。查询请求:POST /<索引名>/_search

1、Constant Score Query

在查询过程中,除了判断文档是否满足查询条件外,ES 还会计算一个 _score 来标识匹配的程度,旨在判断目标文档和查询条件匹配的有多好。该查询将其内部的查询结果文档得分都设定为1或boost的值,多用于结合bool查询实现自定义得分:

POST /book/_search
{
	"query":{
		"constant_score": {
			"filter": {"match": {"title": "细说"}}
		}
	}
}

2、Bool Query

布尔查询由一个或多个布尔子句组成,主要包含如下4个:

-说明
filter只过滤符合条件的文档,不计算相关性得分。ES针对filter会有智能缓存,因此其执行效率很高。做简单匹配查询且不靠谱算分时,推荐使用filter替代query等
must文档必须符合must中的所有条件,会影响相关性得分
must_not文档必须不符合must_not中的所有条件
should文档可以符合should中的条件,会影响相关性得分

查询 title 是 “细说Elasticsearch” 的或者 country 是 “China” 这个关键词的,而且字数是 20000 的结果:

POST /book/_search
{
	"query":{
		"bool": {
			"should": [
				{"match": {"title": "细说Elasticsearch"}},
				{"match": {"country": "China"}}
			],
			"filter": [
	  			{"term": {"word_count": 20000}}
	  		]
		}
	}
}

如果把 should 替换为 must 则为 “与” 的逻辑,还有 must_not 表示一定不满足。

3、Query Context VS Filter Context

上下文类型执行类型使用方式
Query查找与查询语句最匹配的文档,对所有文档进行相关性算分并排序query;bool中的must和should
Filter查找与查询语句相匹配的文档bool中的filter和must_not;constant_score中的filter
4.Count API

1、获取符合条件的文档数,查询请求:POST /<索引名>/_count

POST /book/_count
{
  "query": {
    "match": {
      "title": "细说"
    }
  }
}

5.Source Filtering

1、过滤返回结果中 _source 中的字段,查询请求:POST /<索引名>/_search

不返回字段:

POST /book/_search
{
	"_source":false
}

返回部分字段:

POST /book/_search
{
	"_source":["title","desc"]
}

返回部分字段(通配符):

POST /book/_search
{
	"_source":{
		"includes":"*t*",
		"excludes":"author"
	}
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值