2、GET API
get API 可以通过文档id从索引中获取json格式的文档,以下示例从twitter
索引中获取type
为_doc
,id值为0为的JSON文档:
GET twitter/_doc/0
返回结果:
{
"_index" : "twitter",
"_type" : "_doc",
"_id" : "0",
"_version" : 1,
"_seq_no" : 10,
"_primary_term" : 1,
"found": true,
"_source" : {
"user" : "kimchy",
"date" : "2009-11-15T14:12:12",
"likes": 0,
"message" : "trying out Elasticsearch"
}
}
上述返回结果包含文档的_index, _type, _id 和_version 字段。如果 found
字段为ture
, 就会返回_source
字段,即文档内容。
这个API 可以使用HEAD
方法查询文档是否存在:
HEAD twitter/_doc/0
2.1 实时(Realtime)
get API 默认是实时的,不会受索引刷新率影响(即数据从索引到搜索时可见的那个延迟时间)。如果文档已更新但还没刷新,get API将在适当位置发出刷新调用,这还将使上次刷新后更改的其他文档可见。为了禁用get API的实时性,你可以设置 realtime=false
。
2.2 文档过滤(Source filtering)
get操作默认会返回_source
字段的内容,如果你不想返回该字段,可以使用stored_fields
或_source
参数设置为false
。
GET twitter/_doc/0?_source=false
如果你仅仅需要返回一个或两个字段,你可以使用_source_include
和 _source_exclude
参数来包含或筛选你需要的字段。这对于大型文档尤其有用,因为这样可以降低网络开销。两个参数都采用逗号分隔的字段列表或通配符表达式:
GET twitter/_doc/0?_source_includes=*.id&_source_excludes=entities
你也可以使用_source
参数指定要返回的字段:
GET twitter/_doc/0?_source=*.id,retweeted
2.3 已保存的字段(Stored Fields)
mappings中的store=false
是为了减少存储的字段(如果要使用store_fields,你应该要禁用_source
,即不保存源文档,如果你开启了_source
那么stored_fileds
就没什么用途了,stored_fileds
就像sphinx
的属性一样用于搜索,而_source
就是数据库的数据,一般为了节省内存都不会存储所有字段,只存储需要搜索的字段,或者只存储id)。
get操作指定一组stored_fields
用于获取已存储的字段(默认不会存储字段值,但可以搜索出文档id,你需要在mappings
中指定store=true
)。如果请求字段没有被存储(即字段的store=false
),他们将会被忽略。例如,考虑如下的mappings:
PUT twitter
{
"mappings": {
"_doc": {
"properties": {
"counter": {
"type": "integer",
"store": false
},
"tags": {
"type": "keyword",
"store": true
}
}
}
}
}
现在我们添加一个文档
PUT twitter/_doc/1
{
"counter" : 1,
"tags" : ["red"]
}
然后访问他:
GET twitter/_doc/1?stored_fields=tags,counter
上述操作的结果:
{
"_index": "twitter",
"_type": "_doc",
"_id": "1",
"_version": 1,
"_seq_no" : 22,
"_primary_term" : 1,
"found": true,
"fields": {
"tags": [
"red"
]
}
}
已存储的字段值会以fields数组形式返回。因为counter
字段的stored
为false
,所以GET时会被忽略。
也可以用_routing
检索元数据字段:
PUT twitter/_doc/2?routing=user1
{
"counter" : 1,
"tags" : ["white"]
}
GET twitter/_doc/2?routing=user1&stored_fields=tags,counter
响应结果:
{
"_index": "twitter",
"_type": "_doc",
"_id": "2",
"_version": 1,
"_seq_no" : 13,
"_primary_term" : 1,
"_routing": "user1",
"found": true,
"fields": {
"tags": [
"white"
]
}
}
使用stored_field选项,仅仅叶子(即基础数据类型)字段值会被返回,对象类型的字段值不能返回,当要求返回对象类型的字段值会报错。
2.4 直接获取_source(Getting the _source directly)
用/{index}/{type}/{id}/_source
API可以仅获取文档的_source
字段,而不会获取其他额外的信息,如:
GET twitter/_doc/1/_source
你可以指定需要返回的字段
GET twitter/_doc/1/_source?_source_includes=*.id&_source_excludes=entities
你也可以用_source_include
和_source_exclude
字段控制_source返回哪些字段,不返回哪些字段:
GET twitter/tweet/1/_source?_source_include=*.id&_source_exclude=entities'
你也可以使用HEAD API
查询某个文档的_source
是否存在(如果在mappings的禁用_source,文档将不会保存源数据)。
HEAD twitter/_doc/1/_source
2.5 路由(Routing)
当Index的时候指定了routing
参数,为了得到指定的文档,你Get的时候也需要指定同样的routing
参数:
GET twitter/_doc/2?routing=user1
以上将根据user1进行路由获得id为2的文档。请注意,在没有正确路由的情况下get操作将不会得到正确的结果。
2.6 首选分片(Preference)
preference
参数可以控制在哪个分片上优先执行get请求。默认是在主分片与副本分片之间随机查询的。
preference`可以设置为:
- _primary
- get 请求只在主分片执行
- _local
- get 请求尽可能地在本地分配的分片上执行
- 自定义(字符串)值
- 同一个自定义的值将会访问同一个分片。这使得你的数据访问具有一致性,例如第一次访问副本分片,然后主分片的数据发生变化,但副本分片还没来得及更新;此时,第二次访问的是主分片,将获取到新的数据;第三次访问的是副本分片时获取的数据却是旧数据。为了避免这种情况,你可以指定一个自定义的值,例如用户名或sessionid,使随后每次访问的分片都和第一次访问的分片一样。
2.7 刷新(Refresh)
为了在get操作之前刷新相关的分片并使其可被搜索,可以将refresh
参数设置为true
。将其设置为true之前你应该在仔细考虑并验证这会不会导致系统负载过重(并减慢索引速度)
2.8 分布式(Distributed)
get操作会通过hash路由到一个指定的分片id上执行,然后被重定向到该shard id中的一个副本(即副本分片和主分片是等价的,elasticsearch遵循对等协议),最后选择其中的一个作为实际查询的分片。这意味着我们拥有的副本分片越多,扩展性就越好。
2.9 版本支持(Versioning support)
你可以指定version
参数用来获取version值和指定参数值一致的文档。对于所有版本类型,此行为都相同,但始终检索文档的版本类型force除外。请注意,force版本类型已弃用。
当你更新文档时,elasticsearch 会标记旧版本的文档为删除状态,并使其不能被查询到,然后再创建一个新的文档。也就是说旧版本的文档不会立即消失,但您将无法访问它。当您继续索引更多数据时,Elasticsearch会在后台清除具有删除标记的文档。