文章目录
-------------------------------正文分割线---------------------------
简介
所有其他语言可以使用 RESTful API 通过端口 9200 和 Elasticsearch 进行通信 。一个 Elasticsearch 请求和任何 HTTP 请求一样由若干相同的部件组成:
curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
被 < >
标记的部件:
部件名 | 作用 |
---|---|
VERB | 适当的 HTTP 方法 或 谓词 : GET 、 POST 、 PUT 、 HEAD 或者 DELETE 。 |
PROTOCOL | http 或者 https (如果你在 Elasticsearch 前面有一个 https 代理) |
HOST | Elasticsearch 集群中任意节点的主机名,或者用 localhost 代表本地机器上的节点。 |
PORT | 运行 Elasticsearch HTTP 服务的端口号,默认是 9200 。 |
PATH | API 的终端路径(例如 _count 将返回集群中文档数量)。Path 可能包含多个组件,例如:_cluster/stats 和 _nodes/stats/jvm 。 |
QUERY_STRING | 任意可选的查询字符串参数 (例如 ?pretty 将格式化地输出 JSON 返回值,使其更容易阅读) |
BODY | 一个 JSON 格式的请求体 (如果请求需要的话) |
例如: 计算集群中文档的数量
curl -XGET 'http://localhost:9200/_count?pretty' -d '
{
"query": {
"match_all": {}
}
}
'
1. 文档管理(CRUD)
1.1 创建索引 POST
在ElasticSearch索引中,对应于CRUD中的“创建”和“更新” - 如果对具有给定类型的文档进行索引,并且要插入原先不存在的ID。 如果具有相同类型和ID的文档已存在,则会被覆盖。
要索引第一个JSON对象,我们对REST API创建一个PUT请求到一个由索引名称,类型名称和ID组成的URL。 也就是:http://localhost:9200/<index>/<type>/[<id>]
。
索引和类型是必需的,而id
部分是可选的。如果不指定ID
,ElasticSearch会为我们生成一个ID
。 但是,如果不指定id,应该使用HTTP的POST
而不是PUT
请求。
索引名称是任意的。如果服务器上没有此名称的索引,则将使用默认配置来创建一个索引。
至于类型名称,它也是任意的。 它有几个用途,包括:
- 每种类型都有自己的ID空间。
- 不同类型具有不同的映射(“模式”,定义属性/字段应如何编制索引)。
- 搜索多种类型是可以的,并且也很常见,但很容易搜索一种或多种指定类型。
可以把任何东西放到索引中,只要它可以表示为单个JSON对象。例如,这是一个用户对象信息:
{
"username": "hzs",
"password": "123456",
"age": "18"
}
要创建一个索引,这里使用索引的名称为“db”,类型名称(“user”)和id(“1”),并按照上述模式使用JSON对象在正文中进行请求。
# 用curl请求
curl -XPUT "http://localhost:9200/db/user/1" -d'
{
"username": "hzs",
"password": "123456",
"age": "18"
}'
# 在elastichsearch-head中,或postman(一个道理)
POST /db/user/1
{
"username": "hzs",
"password": "123456",
"age": "18"
}
POST /db/user/2
{
"username": "hzs02",
"password": "123456",
"age": "18"
}
执行请求后,这其实就往索引为 db
类型为 user
的数据库中插入一条 id
为 1 的一条数据,这条数据其实就相当于一个拥有 username/password/age
三个属性的一个实体,就是 JSON 数据。ElasticSearch响应的JSON对象如下所示:
{
"_index": "db",
"_type": "user",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
响应对象包含有关索引操作的信息,例如它是否成功(“ok”)和文档ID,如果不指定则ElasticSearch会自己生成一个。
version
是版本号的意思,当我们执行操作会自动加 1
1.2 更新索引 PUT
现在,在索引中有了user信息,要更新它的话,只需使用相同的ID索引它。
使用与之前相同结构的索引请求,还可以扩展JSON对象。
curl -XPUT "http://localhost:9200/db/user/1" -d'
{
// 更改了姓名
"username": "hzs01",
"password": "123456",
"age": "18",
// 添加了性别
"sex": "男"
}'
ElasticSearch的响应结果与前面的大体上一样,结果对象中的_version
属性的值由1变为2
。响应结果如下。
版本号(_version
)可用于跟踪文档已编入索引的次数。它的主要目的是允许乐观的并发控制,因为可以在索引请求中提供一个版本,如果提供的版本高于索引中的版本,ElasticSearch将只覆盖文档内容,ID值不变,版本号自动添加。
1.3 根据ID查询文档/索引 GET
如果只是想检索一个具有已知ID的索引,一个方法是搜索索引中的文档。另一个简单而快速的方法是通过ID
,使用GET
来检索它。
简单的做法是向同一个URL发出一个GET请求,URL的ID部分是强制性的。通过ID从ElasticSearch中检索文档可发出URL的GET请求:
http://localhost:9200/<index>/<type>/<id>
。
使用以下请求尝试获取user信息:
curl -XGET "http://localhost:9200/db/user/1" -d''
现有如下数据:
执行结果如下所示
1.4 删除文档 DELETE
为了通过ID从索引中删除单个指定的文档,使用与获取索引文档相同的URL,只是这里将HTTP方法更改为DELETE
。
curl -XDELETE "http://localhost:9200/db/user/1" -d''
DELETE /db/user/1
Elasticsearch 返回数据如下:
这里就可以看到 version
由2变成了 3
2. 搜索
添加一些示例数据。使用以下这些请求和数据对象来创建索引。
操作如下:
curl -XPUT "http://localhost:9200/movies/movie/1" -d'
{
"title": "The Godfather",
"director": "Francis Ford Coppola",
"year": 1972,
"genres": ["Crime", "Drama"]
}'
curl -XPUT "http://localhost:9200/movies/movie/2" -d'
{
"title": "Lawrence of Arabia",
"director": "David Lean",
"year": 1962,
"genres": ["Adventure", "Biography", "Drama"]
}'
curl -XPUT "http://localhost:9200/movies/movie/3" -d'
{
"title": "To Kill a Mockingbird",
"director": "Robert Mulligan",
"year": 1962,
"genres": ["Crime", "Drama", "Mystery"]
}'
curl -XPUT "http://localhost:9200/movies/movie/4" -d'
{
"title": "Apocalypse Now",
"director": "Francis Ford Coppola",
"year": 1979,
"genres": ["Drama", "War"]
}'
curl -XPUT "http://localhost:9200/movies/movie/5" -d'
{
"title": "Kill Bill: Vol. 1",
"director": "Quentin Tarantino",
"year": 2003,
"genres": ["Action", "Crime", "Thriller"]
}'
curl -XPUT "http://localhost:9200/movies/movie/6" -d'
{
"title": "The Assassination of Jesse James by the Coward Robert Ford",
"director": "Andrew Dominik",
"year": 2007,
"genres": ["Biography", "Crime", "Drama"]
}'
完成插入后,索引movies中,数据如下所示:
2.1 _search端点
现在已经把一些电影信息放入了索引,可以通过搜索看看是否可找到它们。
为了使用 ElasticSearch 进行搜索,这里选择使用 _search
端点,可选择使用索引和类型。
也就是说,按照以下模式向URL发出请求:<index>/<type>/_search
。其中,index
和 type
都是可选的。
即,为了搜索电影,可以对以下任一URL进行POST请求:
- http://localhost:9200/_search - 搜索所有索引和所有类型。
- http://localhost:9200/movies/_search - 在电影索引中搜索所有类型
- http://localhost:9200/movies/movie/_search - 在电影索引中显式搜索电影类型的文档。
2.2 搜索请求正文和ElasticSearch查询DSL
-
如果只是发送一个请求到上面的URL,我们会得到所有的电影信息。为了创建更有用的搜索请求,还需要向请求正文中提供查询。
-
请求正文是一个JSON对象,除了其它属性以外,它还要包含一个名称为“
query
”的属性,这就可使用ElasticSearch的查询DSL。
{
"query": {
//Query DSL here
}
}
JSON
-
查询DSL是ElasticSearch自己基于JSON的域特定语言,可以在其中表达查询和过滤器。
-
DSL于ES犹如SQL于关系数据库。
2.3 基本自由文本搜索(全文检索)
查询DSL具有一长列不同类型的查询可以使用。 对于“普通”自由文本搜索,最常见的使用为“查询字符串查询”。
查询字符串查询是一个高级查询,有很多不同的选项,ElasticSearch将解析和转换为更简单的查询树。
例如,现在尝试在电影信息中,搜索有包含有“David”这个词的电影:
POST movies/_search
{
"query": {
"query_string": {
"query": "David"
}
}
}
2.4 指定搜索的字段
**“fields”**可用于指定要搜索的字段列表。
如果不使用“fields”字段,ElasticSearch查询将默认自动生成的名为“_all
”的特殊字段,来基于所有文档中的各个字段匹配搜索。即默认全文搜索。
例如,现在要查询,title字段中,含有kill的电影:
curl -XPOST "http://localhost:9200/_search" -d'
{
"query": {
"query_string": {
"query": "kill",
"fields": ["title"]
}
}
}'
2.5 结构化查询
bool联合查询: must, should, must_not
must
: 文档必须完全匹配条件,选择多个即 且 的意思;
should
: should下面会带一个以上的条件,至少满足一个条件,这个文档就符合should,选择多个即 且 的意思;
must_not
: 文档必须不匹配条件,选择多个即 且 的意思;
如果我们想要请求"content中带宝马,但是tag中不带宝马"这样类似的需求,就需要用到bool联合查询。
样例
全文检索,模糊匹配,message.keyword 包含“Error”,项目名称不以“boe”开头的数据。
此处我们需要使用 bool 查询:
GET http://localhost:9200/_search
{
"query":{
"bool":{
"must": [
{
"match_all":{
}
},
{
"wildcard":{
"message.keyword":"*Error*"
}
}
],
"must_not":[
],
"should":[
]
}
},
"from":11,
"size":20,
"sort":[
],
"aggs":{
}
}
2.6 过滤
DSL有各种各样的过滤器可供选择,通过指定"filter"字段,实现过滤功能。
例如,现在,需要找到电影信息包含“drama
”的,年份为1962年的电影,则需要应用一个过滤器,要求“year
”字段等于1962
。
curl -XPOST "http://localhost:9200/_search" -d'
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "drama"
}
}
],
"filter": [
{
"term": { "year": 1962 }
}
]
}
}
}
搜索结果如图所示:
2.7 高级检索语法
-
term
:严格匹配条件,所查询的字段内容要与填入查询框搜索值一致。 -
terms
: query - in检索, 相当于多个term检索, 类似于SQL中in关键字的用法, 即在某些给定的数据中检索。 -
wildcard
:通配符查询,* 表示全匹配,? 表示单一匹配,etc: aaa* 或者 a?b。 -
prefix
:前缀匹配,搜索框如果输入aa,那么可能匹配到的字段值为 aab,aavb等。 -
fuzzy min_similarity
:弹性模糊匹配,有两个搜索框,第一个搜索框为搜索匹配值,会自动纠错,比如输入 ggjk,那么可能会匹配到ggjo,第二个框为最小相似度,采用的算法是Damerau-Levenshtein(最佳字符串对齐)算法。 -
fuzzy max_expansions
:弹性模糊匹配,有两个搜索框,第一个搜索框为搜索匹配值,会自动纠错,比如输入 ggjk,那么可能会匹配到ggjo,第二个框是最大扩展匹配数,比如是1,那么ggjk只会随机模糊匹配到一种可能结果,即使它会出现2种或者更加多,也只会搜索一种。 -
range
:范围查询,gt为大于,gte为大于等于,lt小于,lte小于等于,所搜索的字段值在两个搜索框标识数值
之间。 -
query_string
:字符片段查询,如果是数字,则严格匹配数字,如果是字符串,则按照自身或者分片词匹配。 -
text
:分片词查询,等确定后更新。 -
missing
:查询没有定义该字段或者该字段值为null的数据。
参考网站
https://www.yiibai.com/elasticsearch/elasticsearch-getting-start.html 易百教程
索框为搜索匹配值,会自动纠错,比如输入 ggjk,那么可能会匹配到ggjo,第二个框为最小相似度,采用的算法是Damerau-Levenshtein(最佳字符串对齐)算法。
-
fuzzy max_expansions
:弹性模糊匹配,有两个搜索框,第一个搜索框为搜索匹配值,会自动纠错,比如输入 ggjk,那么可能会匹配到ggjo,第二个框是最大扩展匹配数,比如是1,那么ggjk只会随机模糊匹配到一种可能结果,即使它会出现2种或者更加多,也只会搜索一种。 -
range
:范围查询,gt为大于,gte为大于等于,lt小于,lte小于等于,所搜索的字段值在两个搜索框标识数值
之间。 -
query_string
:字符片段查询,如果是数字,则严格匹配数字,如果是字符串,则按照自身或者分片词匹配。 -
text
:分片词查询,等确定后更新。 -
missing
:查询没有定义该字段或者该字段值为null的数据。
参考网站
https://www.yiibai.com/elasticsearch/elasticsearch-getting-start.html 易百教程