概念
设置索引的时候,我们给某些字段的store属性设置为true,在查询时,请求中可以携带stored_fields
参数,指定某些字段,最后,这些字段会被包含在返回的结果中。如果请求中携带的字段没有被储存,将会被忽略。
示例
默认的场景
我们先观察没有设置store属性的字段情况。
我们新增一个document,并利用自动生成索引功能创建索引:
PUT my_index/_doc/1
{
"content":"这是一个内容",
"title":"这是个标题"
}
GET my_index
#结果
{
"my_index" : {
"aliases" : { },
"mappings" : {
"properties" : {
"content" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"title" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
},
"settings" : {
"index" : {
"creation_date" : "1609764254007",
"number_of_shards" : "1",
"number_of_replicas" : "1",
"uuid" : "uogXMnuyTzOXlM5wfZUmsw",
"version" : {
"created" : "7050099"
},
"provided_name" : "my_index"
}
}
}
}
创建索引时,没有特别设置的话,默认没有store属性
检索数据
get my_index/_search
#结果
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"content" : "这是一个内容",
"title" : "这是个标题"
}
}
]
}
}
默认查询数据,返回的属性字段都在_source中
重新设置store
PUT my_index
{
"mappings":{
"properties": {
"title":{
"type":"text",
"store":false
},
"content":{
"type":"text",
"store":true
}
}
}
}
插入测试数据
PUT my_index/_doc/1
{
"content":"这是一个内容",
"title":"这是个标题"
}
查看索引
{
"my_index" : {
"aliases" : { },
"mappings" : {
"properties" : {
"content" : {
"type" : "text",
"store" : true
},
"title" : {
"type" : "text"
}
}
},
"settings" : {
"index" : {
"creation_date" : "1609764570584",
"number_of_shards" : "1",
"number_of_replicas" : "1",
"uuid" : "1w7VO0gYQV2EXw9SZ6zd8w",
"version" : {
"created" : "7050099"
},
"provided_name" : "my_index"
}
}
}
}
尝试带stored_fields参数去检索
GET my_index/_doc/1?stored_fields=title,content
#结果
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"fields" : {
"content" : [
"这是一个内容"
]
}
}
此时多了名称为fields的字段,并且没有了_source,由于title字段没有存储,当尝试获取stored_fields时get会将其忽略。
总结
其实不管你将store设置为true or false, elasticsearch都将为我们存储这些field, 不同的是:
- 当store为false时(默认配置),这些field只存储在"_source" field中。
- 当store为true时,这些field的value会存储在一个跟
_source
平级的独立的field中。同时也会存储在_source中,所以有两份拷贝。
那么什么情况下需要设置store field呢?一般情况有两种情况:
- _source field在索引的mapping 中disable了。
这种情况下,如果不将某个field定义成store=true,那些将无法在返回的查询结果中看到这个field。 - _source的内容非常大。
这时候如果我们想要在返回的_source document中解释出某个field的值的话,开销会很大(当然你也可以定义source filtering将减少network overhead),比如某个document中保存的是一本书,所以document中可能有这些field: title, date, content。假如我们只是想查询书的title 跟date信息,而不需要解释整个_source(非常大),这个时候我们可以考虑将title, date这些field设置成store=true。