0、概述
在Elasticsearch中,每一个字段的数据都是默认被索引的。也就是说,每个字段专门有一个反向索引用于快速检索。而且,与其它数据库不同,它可以在同一个查询中利用所有的这些反向索引,以惊人的速度返回结果。
1、文档
程序中大多的实体或对象能够被序列化为包含键值对的JSON对象,键(key)是字段(field)或属性(property)的名字,值(value)可以是字符串、数字、布尔类型、另一个对象、值数组或者其他特殊类型,比如表示日期的字符串或者表示地理位置的对象。
{"name": "John Smith","age": 42,"confirmed": true,"join_date": "2014-06-01","home": {"lat": 51.5,"lon": 0.1},"accounts": [{"type": "facebook","id": "johnsmith"},{"type": "twitter","id": "johnsmith"}]
}
通常,我们可以认为对象(object)和文档(document)是等价相通的。不过,他们还是有所差别:对象(Object)是一个JSON结构体——类似于哈希、hashmap、字典或者关联数组;对象(Object)中还可能包含其他对象(Object)。 在Elasticsearch中,文档(document)这个术语有着特殊含义。它特指最顶层结构或者根对象(root object)序列化成的JSON数据(以唯一ID标识并存储于Elasticsearch中)。
一个文档不只有数据。它还包含了元数据(metadata)——关于文档的信息。三个必须的元数据节点是:
节点 | 说明 |
---|---|
_index | 文档存储的地方 |
_type | 文档代表的对象的类 |
_id | 文档的唯一标识 |
2、索引
- 索引一个文档
文档通过index
API被索引——使数据可以被存储和搜索。但是首先我们需要决定文档所在。正如我们讨论的,文档通过其_index
、_type
、_id
唯一确定。们可以自己提供一个_id
,或者也使用index
API 为我们生成一个。
- 使用自己的ID
如果你的文档有自然的标识符(例如user_account
字段或者其他值表示文档),你就可以提供自己的_id
,使用这种形式的index
API:
# _id就等于你设置的id
PUT /{index}/{type}/{id}
{"field": "value",...
}
例如我们的索引叫做“website”
,类型叫做“blog”
,我们选择的ID是“123”
,那么这个索引请求就像这样:
PUT /website/blog/123
{"title": "My first blog entry","text": "Just trying this out...","date": "2014/01/01"
}
Elasticsearch的响应:
{"_index": "website","_type": "blog","_id": "123","_version": 1,"created": true
}
响应指出请求的索引已经被成功创建,这个索引中包含_index
、_type
和_id
元数据,以及一个新元素:_version
。Elasticsearch中每个文档都有版本号,每当文档变化(包括删除)都会使_version
增加。
- 自增ID
POST /website/blog/
{"title": "My second blog entry","text": "Still trying this out...","date": "2014/01/01"
}
响应内容与刚才类似,只有_id
字段变成了自动生成的值:
{"_index": "website","_type": "blog","_id": "wM0OSFhDQXGZAWDf0-drSA","_version": 1,"created": true
}
自动生成的ID有22个字符长,URL-safe, Base64-encoded string universally unique identifiers, 或者叫 UUIDs。
3、获取
- 检索文档
# 在任意的查询字符串中增加pretty参数,类似于上面的例子。
# 会让Elasticsearch美化输出(pretty-print)JSON响应以便更加容易阅读。
# _source字段不会被美化,它的样子与我们输入的一致。
GET /website/blog/123?pretty
- 检索文档的一部分
# 请求个别字段可以使用_source参数。多个字段可以使用逗号分隔
GET /website/blog/123?_source=title,text# 只想得到_source字段而不要其他的元数据
GET /website/blog/123/_source
4、存在
# 只是检查文档是否存在
# 存在200 OK,不存在404 Not Found
HEAD /website/blog/123
5、更新
# Elasticsearch把_version增加了
PUT /website/blog/123
{"title": "My first blog entry","text": "I am starting to get the hang of this...","date": "2014/01/02"
}
6、创建
请记住_index
、_type
、_id
三者唯一确定一个文档。
# Elasticsearch自动生成唯一_id,再次执行,又生成一个_id
POST /website/blog/
{ ... }
然而,如果想使用自定义的_id
,我们必须告诉Elasticsearch应该在_index
、_type
、_id
三者都不同时才接受请求。为了做到这点有两种方法,它们其实做的是同一件事情。你可以选择适合自己的方式:
# 123存在则报错提示文档已经存在,否则创建
# 或者使用PUT /website/blog/123/_create
PUT /website/blog/123?op_type=create
{"title": "My first blog entry","text": "Just tryinsssssg this out...","date": "2014/01/01"
}
7、删除
# 删除id=123的文档
DELETE /website/blog/123# 删除blog删除索引
DELETE /website/
8、局部更新
我们也说过文档是不可变的——它们不能被更改,只能被替换。update
API必须遵循相同的规则。表面看来,我们似乎是局部更新了文档的位置,内部却是使用update
检索-修改-重建索引流程;
# 添加tags字段
POST /website/blog/123/_update
{"doc" : {"tags" : [ "testing" ],"views": 0}
}
9、检索多个文档(Mget)
像Elasticsearch一样,检索多个文档依旧非常快。合并多个请求可以避免每个请求单独的网络开销。如果你需要从Elasticsearch中检索多个文档,相对于一个一个的检索,更快的方式是在一个请求中使用multi-get或者mget
API。
# mget API参数是一个docs数组,数组的每个节点定义一个文档的_index、_type、_id元数据。
# 如果你只想检索一个或几个确定的字段,也可以定义一个_source参数:
POST /_mget
{"docs" : [{"_index" : "website","_type" : "blog","_id" : 2},{"_index" : "website","_type" : "pageviews","_id" : 1,"_source": "views"}]
}
响应体也包含一个docs
数组,每个文档还包含一个响应,它们按照请求定义的顺序排列。每个这样的响应与单独使用get
request响应体相同
{"docs" : [{"_index" : "website","_id" : "2","_type" : "blog","found" : true,"_source" : {"text" : "This is a piece of cake...","title" : "My first external blog entry"},"_version" : 10},{"_index" : "website","_id" : "1","_type" : "pageviews","found" : true,"_version" : 2,"_source" : {"views" : 2}}]
}
10、批量
就像mget
允许我们一次性检索多个文档一样,bulk
API允许我们使用单一请求来实现多个文档的create
、index
、update
或delete
。这对索引类似于日志活动这样的数据流非常有用,它们可以以成百上千的数据为一个批次按序进行索引。
POST /_bulk
{ "delete": { "_index": "website", "_type": "blog", "_id": "123" }} <1>
{ "create": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "title": "My first blog post" }
{ "index": { "_index": "website", "_type": "blog" }}
{ "title": "My second blog post" }
{ "update": { "_index": "website", "_type": "blog", "_id": "123", "_retry_on_conflict" : 3} }
{ "doc" : {"title" : "My updated blog post"} } <2>
11、参考
- 本文内容来源于https://es.xiaoleilu.com/030_Data/55_Bulk.html