设置索引的时候,我们给某些字段的store属性设置为true,在查询时,请求中可以携带stored_fields
参数,指定某些字段,最后,这些字段会被包含在返回的结果中。如果请求中携带的字段没有被储存,将会被忽略。
默认的场景
我们先观察没有设置store属性的字段情况。
我们新增一个document,并利用自动生成索引功能创建索引:
PUT twitter2/_doc/1{"user":"kimchy","post_date":"2009-11-15T14:12:12","message":"trying out Elasticsearch"}
查看index结构
```yaml
GET twitter2{"twitter2":{"aliases":{},"mappings":{"_doc":{"properties":{"message":{ //默认没有store属性"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"post_date":{ //默认没有store属性"type":"date"},"user":{ //默认没有store属性"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}}},
创建索引时,没有特别设置的话,默认没有store属性
检索数据:
{"_index":"twitter2","_type":"_doc","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{ //默认查询数据,返回的属性字段都在_source中"user":"kimchy","post_date":"2009-11-15T14:12:12","message":"trying out Elasticsearch"}}
//默认查询数据,返回的属性字段都在_source中
设置store属性的场景
创建索引twitter
,并设置tags
字段的store
属性为true
:
PUT twitter{"mappings":{"_doc":{"properties":{"counter":{"type":"integer","store": false //默认值就是false},"tags":{"type":"keyword","store": true //修改值为true}}}}}
查看索引:
GET twitter{"twitter":{"aliases":{},"mappings":{"_doc":{"properties":{"counter":{"type": "integer" //没有显示store属性,说明默认值为否},"tags":{"type":"keyword","store": true //store属性为true}}}}
现在我们可以添加 document:
PUT twitter/_doc/1{"counter":1,"tags":["red"]}
尝试带stored_fields参数去检索:
GET twitter/_doc/1?stored_fields=tags,counter
以上get操作的结果是:
{"_index":"twitter","_type":"tweet","_id":"1","_version":1,"found":true,"fields":{ //此时多了名称为fields的字段,并且没有了_source"tags":[ //tags的stroe属性设置为true,因此显示在结果中
"red"]}}
从 document 中获取的字段的值通常是array。
由于counter字段没有存储,当尝试获取stored_fields时get会将其忽略。
总结
其实不管你将store设置为ture 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。