Elasticsearch是一个分布式的搜索和分析引擎,它可以处理大量的数据,并提供快速和灵活的查询功能。但是,当数据集比较大时,Elasticsearch也有一些性能方面的挑战,比如如何有效地存储和检索文档中的字段。这里涉及到三个与字段存储和检索相关的概念:_source、store以及docValues,让我们来详细了解它们的含义、用途、区别及设置方式。
_source字段
_source字段是一个元数据字段,它包含了索引时传入的原始JSON文档的内容,并会被存储,以便在执行获取请求时返回,比如get或search。
_source字段有以下作用:
它可用于更新查询和重索引API,为复杂的查询和分析提供了便利性。
通过实时高亮功能,_source字段使我们能够即时获取文档中的关键信息。
当我们需要从一个Elasticsearch索引重索引到另一个索引以改变映射或分析,或者升级索引到新的主版本时,_source字段是不可或缺的。
对于调试查询或聚合,_source字段允许我们直接查看索引时使用的原始文档,为我们提供了极大的便利。
_source字段的设置方式是:
根据需要启用或禁用_source字段。禁用_source字段虽然可以节省存储空间,但也会失去其上述的许多功能。如果存储空间是一个问题,建议考虑增加压缩级别而不是完全禁用_source字段。根据实际需求,我们可以决定哪些字段应该包含在_source中,哪些字段应该排除在外。需要注意的是,从_source中删除字段可能会带来一些负面影响,特别是当我们需要从一个Elasticsearch索引重索引到另一个索引时。在这种情况下,建议使用源过滤代替。
通过使用源过滤,我们可以精确地控制返回的_source字段的内容。这种过滤可以在搜索请求中指定,也可以在映射中预先设定默认的源过滤。这样可以在保证必要的数据返回的同时,避免不必要的细节泄露。
_source字段的设置示例是:
// 在创建索引时,设置_source字段的enabled属性为false,禁用_source字段
PUT my-index-000001
{
"mappings": {
"_source": {
"enabled": false
}
}
}
// 堆代码 duidaima.com
// 在创建索引时,设置_source字段的exclude参数,排除content字段
PUT my-index-000001
{
"mappings": {
"_source": {
"includes": ["title"]
},
"properties": {
"title": {
"type": "text"
},
"content": {
"type": "text"
}
}
}
}
// 在搜索请求中,使用_source参数,只返回title字段
GET my-index-000001/_search
{
"_source": ["title"],
"query": {
"match_all": {}
}
}
// 在映射中,设置_source字段的includes参数,只包含title字段
PUT my-index-000001
{
"mappings": {
"_source": {
"includes": ["title"]
},
"properties": {
"title": {
"type": "text"
},
"content": {
"type": "text"
}
},
"settings": {
"index.mapping.default_source_excludes": [".source"] // 这将默认排除.source字段,可以根据需要更改或删除此行。
}
}
}
store属性
store属性是一个字段级别的设置,它决定了该字段是否需要被单独存储在Elasticsearch索引中。store属性的作用是在检索时,可以通过stored_fields参数返回指定的字段,而非整个对象,从而节省网络带宽,但是需要额外的存储空间和IO开销。默认情况下,Elasticsearch不会单独存储字段,即store默认为false。但是,如果我们的索引主要用于简单的搜索和过滤,结果只返回极少数字段时,可以考虑将_source禁用,并将store设置为true,以便单独保存该字段。这样可以进一步优化索引的存储和查询性能。
store属性的设置方式是:
在创建索引时,设置字段的store属性为true或false。
在搜索请求中,使用stored_fields参数来返回存储的字段。
store属性的设置示例是:
// 在创建索引时,设置title字段的store属性为true,存储title字段
PUT my-index-000001
{
"mappings": {
"properties": {
"title": {
"type": "text",
"store": true
},
"content": {
"type": "text"
}
}
}
}
// 在搜索请求中,使用stored_fields参数,返回title字段
GET my-index-000001/_search
{
"stored_fields": "title",
"query": {
"match": {
"title": "elasticsearch"
}
}
}
docValues
docValues是一种列式存储结构,它确实可以用于排序、聚合和脚本等操作。docValues存储的值与_source字段相同,但它们以一种更高效的方式组织。docValues的主要作用是提高排序和聚合操作的性能,通过预先计算和存储字段值,docValues避免了在执行这些操作时进行昂贵的磁盘扫描。但是需要额外的存储空间和IO开销。
docValues的默认值是true,也就是说,所有支持docValues的字段都是启用的,除了text和annotated_text类型。如果你确定你不需要对某个字段进行排序,聚合,脚本等操作,你可以禁用docValues,以节省磁盘空间。
docValues的设置方式是:
.在创建索引时,设置字段的doc_values属性为true或false。
.在搜索请求中,使用docvalue_fields参数来返回docValues。
docValues的设置示例是:
// 在创建索引时,设置status_code字段的doc_values属性为true,启用docValues
PUT my-index-000001
{
"mappings": {
"properties": {
"status_code": {
"type": "long",
"doc_values": true
},
"content": {
"type": "text"
}
}
}
}
// 在搜索请求中,使用docvalue_fields参数,返回status_code字段的docValues
GET my-index-000001/_search
{
"source": {
"docvalue_fields": "status_code",
"query": {
"match_all": {}
}
}
}
_source、store和docValues的区别
_source、store和docValues都是与字段存储和检索相关的概念,但是它们有以下的区别:
1._source是一个文档级别的设置,它决定了整个文档的原始JSON是否被存储在Elasticsearch中。store是一个字段级别的设置,它决定了一个字段是否被单独存储在Lucene索引中。docValues是一种列式存储结构,它可以用于排序,聚合,脚本等操作。
2._source字段的默认为true,所有的文档都会存储_source字段。store属性默认为false,除了_source字段之外,其他字段都不会被单独存储。docValues默认为true,所有支持docValues的字段都会启用,除了text和annotated_text类型。
3._source字段的优点是可以保留原始的文档内容,以便进行更新,重索引,高亮等操作。store属性的优点是可以节省带宽,因为只返回需要的字段。docValues的优点是可以提高排序,聚合,脚本等操作的性能。
4._source字段的缺点是可能占用较多的带宽,因为返回的是整个文档。store属性的缺点是需要额外的存储空间和IO开销。docValues的缺点是需要额外的存储空间和IO开销。
5._source、store和docValues对Elasticsearch的性能产生着不同的影响,在不同的场景下有着各自的优点和缺点。Elasticsearch提供了灵活且丰富的选项供我们进行设置,因此,我们需要根据实际需求,选择合适的选项,以使我们的索引更加高效和稳定。