存储的原始数据。_source中的内容就是搜索api返回的内容,如:node
{
"query":{
"term":{
"title":"test"
}
}
}
结果:mysql
{ "took": 2, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 0.2876821, "hits": [ { "_index": "book3", "_type": "english", "_id": "3nuFZ2UBYLvVFwGWZHcJ", "_score": 0.2876821, "_source": { "title": "test!" } } ] } }
默认状况下,Elasticsearch里面有2分内容,一份是原始文档,也就是_source字段里的内容,咱们在Elasticsearch中搜索文档,查看的文档内容就是_source中的内容。另外一份是倒排索引,倒排索引中的数据结构是倒排记录表,记录了词项和文档之间的对应关系。sql
index使用倒排索引存储的是,分析器分析完的词和文档的对应关系。如图:api
在搜索排序的时候,查询倒排索引要比快。数据结构
那么文档索引到Elasticsearch的时候,默认状况下是对全部字段建立倒排索引的(动态mapping解析出来为数字类型、布尔类型的字段除外),某个字段是否生成倒排索引是由字段的index属性控制的,在Elasticsearch 5以前,index属性的取值有三个:app
ES6.3 index属性支持false和true,false不能搜索至关于no,true能够索引。默认使用standar分词svg
默认为no,被store标记的fields被存储在和index不一样的fragment中,以便于快速检索。虽然store占用磁盘空间,可是减小了计算。store的值能够取yes/no或者true/false,默认值是no或者false。测试
若是在{"store":yes}的状况下,ES会对该字段单独存储倒排索引,每次根据ID检索的时候,会多走一次IO来从倒排索引取数据。ui
而若是_source enabled 状况下,ES能够直接根据Client类来解析_source JSON,只需一次IO就将全部字段都检索出来了。spa
若是须要高亮处理,这里就要说到store属性,store属性用于指定是否将原始字段写入索引,默认取值为no。若是在Lucene中,高亮功能和store属性是否存储息息相关,由于须要根据偏移位置到原始文档中找到关键字才能加上高亮的片断。在Elasticsearch,由于_source中已经存储了一份原始文档,能够根据_source中的原始文档实现高亮,在索引中再存储原始文档就多余了,因此Elasticsearch默认是把store属性设置为no。
注意:若是想要对某个字段实现高亮功能,_source和store至少保留一个。
_all: 在6.0+ 中 , 该字段 默认被禁用,建议使用copy_to。再说_all字段,顾名思义,_all字段里面包含了一个文档里面的全部信息,是一个超级字段。以图中的文档为例,若是开启_all字段,那么title+content会组成一个超级字段,这个字段包含了其余字段的全部内容,空格隔开。固然也能够设置只存储某几个字段到_all属性里面或者排除某些字段。适合一次搜索整个文档。
_source字段默认是存储的, 什么状况下不用保留_source字段?若是某个字段内容很是多,业务里面只须要能对该字段进行搜索,最后返回文档id,查看文档内容会再次到mysql或者hbase中取数据,把大字段的内容存在Elasticsearch中只会增大索引,这一点文档数量越大结果越明显,若是一条文档节省几KB,放大到亿万级的量结果也是很是可观的。
若是想要关闭_source字段,在mapping中的设置以下:
{ "yourtype":{ "_source":{ "enabled":false }, "properties": { ... } } }
若是只想存储某几个字段的原始值到Elasticsearch,能够经过incudes参数来设置,在mapping中的设置以下:
{ "yourtype":{ "_source":{ "includes":["field1","field2"] }, "properties": { ... } } }
一样,能够经过excludes参数排除某些字段:
{ "yourtype":{ "_source":{ "excludes":["field1","field2"] }, "properties": { ... } } }
测试,首先建立一个索引:
PUT book2
设置mapping,禁用_source:
POST book2/english/_mapping
{ "book2": { "_source": { "enabled": false } } }
插入数据:
POST /book2/english/ { "title":"test!", "content":"test good Hellow" }
搜索"test"
POST book2/_search { "query":{ "term":{ "title":"test" } } }
结果,只返回了id,没有_suorce,任然能够搜索到。
{ "took": 5, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 0.2876821, "hits": [ { "_index": "book2", "_type": "english", "_id": "zns1Z2UBYLvVFwGW4Hea", "_score": 0.2876821 } ] } }
当_source=false,store和index必须有一个为true,原始数据不保存,倒排索引必需要存储,不然去哪里查询呢,验证下:
POST book3/english/_mapping { "english":{ "_source": { "enabled": false }, "properties": { "content":{ "type":"text", "store":"false", "index":"no" }, "title":{ "type":"text", "store":"false", "index":"no" } } } }
报错:
{ "error": { "root_cause": [ { "type": "illegal_argument_exception", "reason": "Could not convert [content.index] to boolean" } ], "type": "illegal_argument_exception", "reason": "Could not convert [content.index] to boolean", "caused_by": { "type": "illegal_argument_exception", "reason": "Failed to parse value [no] as only [true] or [false] are allowed." } }, "status": 400 }
{ "yourtype": { "_all": { "enabled": true }, "properties": { ... } } }
也能够经过在字段中指定某个字段是否包含在_all中:
{ "yourtype": { "properties": { "field1": { "type": "string", "include_in_all": false }, "field2": { "type": "string", "include_in_all": true } } } }
若是要把字段原始值保存,要设置store属性为true,这样索引会更大,须要根据需求使用。下面给出测试代码。
建立test索引:
DELETE book2
PUT book2
copy_to语法:
POST book2/english/_mapping { "english":{ "properties": { "content":{ "type":"text", "copy_to":"all_text" }, "title":{ "type":"text", "copy_to":"all_text" }, "all_text":{ "type":"text" } } } }
插入数据:
POST /book2/english/ { "title":"test!", "content":"test good Hellow" }
查询:
POST book2/_search{
"query":{
"term":{
"all_text":"test"
}
}
}
结果:
{ "took": 13, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 2, "max_score": 0.39556286, "hits": [ { "_index": "book2", "_type": "english", "_id": "0HtjZ2UBYLvVFwGWl3f7", "_score": 0.39556286, "_source": { "title": "test!god", "content": "test good Hellow" } }, { "_index": "book2", "_type": "english", "_id": "z3tjZ2UBYLvVFwGWWXd3", "_score": 0.39556286, "_source": { "title": "test!", "content": "test good Hellow" } } ] } }
"index":false设置不可搜索
POST book3/english/_mapping { "english":{ "_source": { "enabled": false }, "properties": { "content":{ "type":"text", "store":true, "index":false }, "title":{ "type":"text", "store":true, "index":false } } } }
查询:
POST book3/_search { "query":{ "term":{ "content":"test" } } } 结果: { "error": { "root_cause": [ { "type": "query_shard_exception", "reason": "failed to create query: {\n \"term\" : {\n \"content\" : {\n \"value\" : \"test\",\n \"boost\" : 1.0\n }\n }\n}", "index_uuid": "FvNPHNb7Sa6H757_lKRhpg", "index": "book3" } ], "type": "search_phase_execution_exception", "reason": "all shards failed", "phase": "query", "grouped": true, "failed_shards": [ { "shard": 0, "index": "book3", "node": "R8t6R20XQritJB_5QVQsvg", "reason": { "type": "query_shard_exception", "reason": "failed to create query: {\n \"term\" : {\n \"content\" : {\n \"value\" : \"test\",\n \"boost\" : 1.0\n }\n }\n}", "index_uuid": "FvNPHNb7Sa6H757_lKRhpg", "index": "book3", "caused_by": { "type": "illegal_argument_exception", "reason": "Cannot search on field [content] since it is not indexed." } } } ] }, "status": 400 }
正确配置:
POST book3/english/_mapping { "english":{ "_source": { "enabled": false }, "properties": { "content":{ "type":"text", "store":true, "index":"true" }, "title":{ "type":"text", "store":true, "index":"true" } } } }
高亮:
{ "query":{ "term":{ "title":"test" } }, "highlight":{ "fields":{ "title":{} } } }
结果:
{ "took": 4, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 0.2876821, "hits": [ { "_index": "book3", "_type": "english", "_id": "2nt_Z2UBYLvVFwGWfXcn", "_score": 0.2876821, "highlight": { "title": [ "<em>test</em>!" ] } } ] } }