文档通过index API被索引——使数据可以被存储和搜索。但是首先我们需要决定文档所在。正如我们讨论的,文档通过其_index、_type、_id唯一确定。我们可以自己提供一个_id,或者也使用index API为我们生成一个。
如果你的文档有自然的标识符(例如user_account字段或者其他值表示文档),你就可以提供自己的_id,使用这种形式的index API:
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、_type和_id元数据,以及一个新元素:_version。
Elasticsearch中每个文档都有版本号,每当文档变化(包括删除)都会使_version增加。
如果我们的数据没有自然ID,我们可以让Elasticsearch自动为我们生成。请求结构发生了变化:PUT方法——“在这个URL中存储文档”变成了POST方法——“在这个文档下存储文档”。(注:原来是把文档存储到某个ID对应的空间,现在是把这个文档添加到某个_type下。)
URL现在只包含_index和_type两个字段:
POST /website/blog/
{
"title" : "My second blog entry",
"text" : "Still trying this out...",
"date" : "2014/01/01"
}
响应内容与刚才类似,只有_id字段变成了自动生成的值:
自动生成的ID有22个字符长,URL-safe,Base64-encoded string university unique identifiers,或者叫UUIDs。
想要从Elasticsearch中获取文档,我们使用同样的_index、_type、_id,但是HTTP方法改为GET:
GET /website/blog/123?pretty
响应包含了现在熟悉的元数据节点,增加了_source字段,它包含了在创建索引时我们发送给Elasticsearch的原始文档。
pretty,在任意的查询字符串中增加pretty参数,类似于上面的例子。会让Elasticsearch美化输出(pretty-print)JSON响应以便更加容易阅读。_source字段不会被美化,他的样子与我们输入的一致。
GET请求返回的响应内容包含{"found" : true}。这意味着文档已经找到。如果我们请求一个不存在的文档,依旧会得到一个JSON,不过found值变成了false。
此外,HTTP响应状态码也会变成'404 Not Found'代替‘200 OK’。我们可以在curl后加-i参数得到响应头:
curl -i XGET http://localhost:9200/website/blog/124?pretty
现在响应类似于这样:
通常,GET请求将返回文档的全部,存储在_source参数中。但是可能你感兴趣的字段只是title。请求个别字段可以使用_source参数。多个字段可以使用逗号分隔:
GET /website/blog/123?_source=title,text
_source字段现在只包含我们请求的字段,而且过滤了date字段:
或者你只想得到_source字段而不要其他的元数据,你可以这样请求:
GET /website/blog/123/_source
它仅仅返回:
如果你想做的只是检查文档是否存在——你对内容完全不感兴趣——使用HEAD方法来代替GET。HEAD请求不会返回响应体,只有HTTP头:
curl -i -XHEAD http://localhost:9200/website/blog/123
Elasticsearch将会返回200 OK状态,如果你的文档存在:
如果不存在返回404 Not Found:
当然,这只表示你在查询的那一刻文档不存在,但并不表示几毫秒后依旧不存在。另一个进程在这期间可能创建新文档。
文档在Elasticsearch中是不可变的——我们不能修改他们。如果需要更新已存在的文档,我们可以使用index API重建索引(reindex)或者替换掉它。
PUT /website/blog/123
{
"title" : "My first blog entry",
"text" : "I am starting to get the hang of this...",
"date" : "2014/01/02"
}
在响应中,我们可以看到Elasticsearch把_version增加了。
<1> created标识为false因为同索引、同类型下已经存在同ID的文档。
在内部,Elasticsearch已经标记旧文档为删除并添加了一个完整的新文档。旧版本文档不会立即消失,但你也不能去访问它。Elasticsearch会在你继续索引更多数据时清理被删除的文档。
update API似乎允许你修改文档的局部,但事实上Elasticsearch遵循与之前所说完全相同的过程,这个过程如下:
唯一的不同是update API完成这一过程只需要一个客户端请求即可,不再需要get和index请求了。
当索引一个文档,我们如何确定是完全创建了一个新的还是覆盖了一个已经存在的呢?
请记住_index、_type、_id三者唯一确定一个文档。所以要想保证文档是新加入的,最简单的方式是使用POST方法让Elasticsearch自动生成唯一_id:
POST /website/blog/
{...}
然而,如果想使用自定义的_id,我们必须告诉Elasticsearch应该在_index、_type、_id三者都不同时才能接受请求。为了做到这点有两种方法,他们其实做的是同一件事情。你可以选择适合自己的方式:
第一种方法使用op_type查询参数:
PUT /website/blog/123?op_type=create
{ ... }
或者第二种方法是在URL后加/_create作为端点:
PUT /website/blog/123/_create
{ ... }
如果请求成功的创建了一个新文档,Elasticsearch将返回正常的元数据且响应状态码是201 Created。
另一方面,如果包含相同的_index、_type和_id的文档已经存在,Elasticsearch将返回409 Conflict响应状态码,错误信息类似如下:
删除文档的语法模式与之前基本一致,只不过要使用DELETE方法:
DELETE /website/blog/123
如果文档被找到,Elasticsearch将返回200 OK状态码和以下响应体。注意_version数字已经增加了。
如果文档未找到,我们将得到一个404 Not Found状态码,响应体是这样的:
尽管文档不存在——“found”的值是false——_version依旧增加了。这是内部记录的一部分,它确保在多节点间不同操作可以有正确的顺序。
注意:删除一个文档也不会立即从磁盘上移除,它只是被标记成已删除。Elasticsearch将会在你之后添加更多的索引的时候才会在后台进行删除内容的清理。
因篇幅问题不能全部显示,请点此查看更多更全内容