设置索引的时候,我们给某些字段的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。