ElasticSearch什么是文档?索引一个文档

来源:互联网 发布:java attribute用法 编辑:程序博客网 时间:2024/05/01 17:20

什么是文档?

程序中大多的实体或对象能够被序列化为包含键值对的JSON对象,键(key)字段(field)属性(property)的名字,值(value)可以是字符串、数字、布尔类型、另一个对象、值数组或者其他特殊类型,比如表示日期的字符串或者表示地理位置的对象。

1

{    "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中)。

1

文档元数据

一个文档不只有数据。它还包含了元数据(metadata)——关于文档的信息。三个必须的元数据节点是:

节点说明_index文档存储的地方_type文档代表的对象的类_id文档的唯一标识

_index

索引(index)类似于关系型数据库里的“数据库”——它是我们存储和索引关联数据的地方。

提示:

事实上,我们的数据被存储和索引在分片(shards)中,索引只是一个把一个或多个分片分组在一起的逻辑空间。然而,这只是一些内部细节——我们的程序完全不用关心分片。对于我们的程序而言,文档存储在索引(index)中。剩下的细节由Elasticsearch关心既可。

1

我们将会在《索引管理》章节中探讨如何创建并管理索引,但现在,我们将让Elasticsearch为我们创建索引。我们唯一需要做的仅仅是选择一个索引名。这个名字必须是全部小写,不能以下划线开头,不能包含逗号。让我们使用website做为索引名。

1

_type

在应用中,我们使用对象表示一些“事物”,例如一个用户、一篇博客、一个评论,或者一封邮件。每个对象都属于一个类(class),这个类定义了属性或与对象关联的数据。user类的对象可能包含姓名、性别、年龄和Email地址。

1

在关系型数据库中,我们经常将相同类的对象存储在一个表里,因为它们有着相同的结构。同理,在Elasticsearch中,我们使用相同类型(type)的文档表示相同的“事物”,因为他们的数据结构也是相同的。

每个类型(type)都有自己的映射(mapping)或者结构定义,就像传统数据库表中的列一样。所有类型下的文档被存储在同一个索引下,但是类型的映射(mapping)会告诉Elasticsearch不同的文档如何被索引。 我们将会在《映射》章节探讨如何定义和管理映射,但是现在我们将依赖Elasticsearch去自动处理数据结构。

_type的名字可以是大写或小写,不能包含下划线或逗号。我们将使用blog做为类型名。

_id

id仅仅是一个字符串,它与_index_type组合时,就可以在Elasticsearch中唯一标识一个文档。当创建一个文档,你可以自定义_id,也可以让Elasticsearch帮你自动生成。

其它元数据

还有一些其它的元数据,我们将在《映射》章节探讨。使用上面提到的元素,我们已经可以在Elasticsearch中存储文档并通过ID检索——换言说,把Elasticsearch做为文档存储器使用了。



索引一个文档

文档通过index API被索引——使数据可以被存储和搜索。但是首先我们需要决定文档所在。正如我们讨论的,文档通过其_index_type_id唯一确定。们可以自己提供一个_id,或者也使用index API 为我们生成一个。

1

使用自己的ID

如果你的文档有自然的标识符(例如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":    "website",   "_type":     "blog",   "_id":       "123",   "_version":  1,   "created":   true}

响应指出请求的索引已经被成功创建,这个索引中包含_index_type_id元数据,以及一个新元素:_version

2

Elasticsearch中每个文档都有版本号,每当文档变化(包括删除)都会使_version增加。在《版本控制》章节中我们将探讨如何使用_version号确保你程序的一部分不会覆盖掉另一部分所做的更改。

自增ID

如果我们的数据没有自然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字段变成了自动生成的值:

2

{   "_index":    "website",   "_type":     "blog",   "_id":       "wM0OSFhDQXGZAWDf0-drSA",   "_version":  1,   "created":   true}

自动生成的ID有22个字符长,URL-safe, Base64-encoded string universally unique identifiers, 或者叫 UUIDs。



检索文档

想要从Elasticsearch中获取文档,我们使用同样的_index_type_id,但是HTTP方法改为GET

GET /website/blog/123?pretty

响应包含了现在熟悉的元数据节点,增加了_source字段,它包含了在创建索引时我们发送给Elasticsearch的原始文档。

{  "_index" :   "website",  "_type" :    "blog",  "_id" :      "123",  "_version" : 1,  "found" :    true,  "_source" :  {      "title": "My first blog entry",      "text":  "Just trying this out...",      "date":  "2014/01/01"  }}

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

现在响应类似于这样:

HTTP/1.1 404 Not FoundContent-Type: application/json; charset=UTF-8Content-Length: 83{  "_index" : "website",  "_type" :  "blog",  "_id" :    "124",  "found" :  false}

检索文档的一部分

通常,GET请求将返回文档的全部,存储在_source参数中。但是可能你感兴趣的字段只是title。请求个别字段可以使用_source参数。多个字段可以使用逗号分隔:

GET /website/blog/123?_source=title,text

_source字段现在只包含我们请求的字段,而且过滤了date字段:

{  "_index" :   "website",  "_type" :    "blog",  "_id" :      "123",  "_version" : 1,  "exists" :   true,  "_source" : {      "title": "My first blog entry" ,      "text":  "Just trying this out..."  }}

或者你只想得到_source字段而不要其他的元数据,你可以这样请求:

GET /website/blog/123/_source

它仅仅返回:

{   "title": "My first blog entry",   "text":  "Just trying this out...",   "date":  "2014/01/01"}


检查文档是否存在

如果你想做的只是检查文档是否存在——你对内容完全不感兴趣——使用HEAD方法来代替GETHEAD请求不会返回响应体,只有HTTP头:

curl -i -XHEAD http://localhost:9200/website/blog/123

Elasticsearch将会返回200 OK状态如果你的文档存在:

HTTP/1.1 200 OKContent-Type: text/plain; charset=UTF-8Content-Length: 0

如果不存在返回404 Not Found

curl -i -XHEAD http://localhost:9200/website/blog/124
HTTP/1.1 404 Not FoundContent-Type: text/plain; charset=UTF-8Content-Length: 0

当然,这只表示你在查询的那一刻文档不存在,但并不表示几毫秒后依旧不存在。另一个进程在这期间可能创建新文档。



更新整个文档

文档在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

{  "_index" :   "website",  "_type" :    "blog",  "_id" :      "123",  "_version" : 2,  "created":   false <1>}
  • <1> created标识为false因为同索引、同类型下已经存在同ID的文档。

在内部,Elasticsearch已经标记旧文档为删除并添加了一个完整的新文档。旧版本文档不会立即消失,但你也不能去访问它。Elasticsearch会在你继续索引更多数据时清理被删除的文档。

在本章的后面,我们将会在《局部更新》中探讨update API。这个API 似乎 允许你修改文档的局部,但事实上Elasticsearch遵循与之前所说完全相同的过程,这个过程如下:

  1. 从旧文档中检索JSON
  2. 修改它
  3. 删除旧文档
  4. 索引新文档

唯一的不同是update API完成这一过程只需要一个客户端请求既可,不再需要getindex请求了。



from: https://es.xiaoleilu.com/030_Data/05_Document.html

0 0
原创粉丝点击