# 一些建议

原文链接 : [https://www.elastic.co/guide/en/elasticsearch/reference/5.3/general-recommendations.html](https://www.elastic.co/guide/en/elasticsearch/reference/5.3/general-recommendations.html)

译文链接 : [一些建议](/pages/viewpage.action?pageId=10027109)

贡献者 : @李坚，[ApacheCN](/display/~apachecn)，[Apache中文网](/display/~apachechina)

## 不要返回大的结果集

Elasticsearch被设计为一个搜索引擎，这使得它非常好地获取与查询匹配的顶级文档。 但是，它对于落入数据库域的工作负载并不好，例如检索与特定查询匹配的所有文档。 如果需要这样做，请确保使用Scroll API。

## 避免大文件

假设默认_**http.max_context_length**_ 的设置为100MB，_Elasticsearch_ 将拒绝索引大于该值的任何文档。 您可能会决定增加该特定设置，但是Lucene的限制约为2GB。

即使没有考虑到硬限制，大型文件通常也不实用。即使搜索请求不需要 _source，大型文档也会对网络，内存使用和磁盘造成更大的压力，因为在所有情况下，Elasticsearch 需要获取文档的_id，并且获取此字段的成本将大于大文档工作时占用的文件系统缓存。索引这个大文档所占用的内存是一个普通文档的乘数倍。邻近搜索（例如短语查询）和高亮显示也变得花费更多系统资源，因为它们的花费的系统资源成本直接取决于原始文档的大小。

重新考虑信息的单位应该是有用的。例如，您想要使书籍可搜索，并不意味着可搜索的这个文档应该由整本书组成。使用章节甚至段落作为文档可能是一个更好的办法，然后在这些文档中有一个属性标识他们属于哪本书。这不仅避免了大文件的问题，还使搜索体验更好。例如，如果用户搜索两个单词foo和bar，则不同章节中的匹配可能非常差，而同一段落中的匹配可能很好。

## 避免稀疏

Elasticsearch 依赖于索引和存储数据的 Lucene 后面的数据结构最适用于密集数据，比如，当所有文档都有相同的字段的时候。对于启用规范的字段（默认情况下为文本字段）或启用了文档值（默认情况下为数字，日期，IP和关键字）的情况尤其如此。

原因是 Lucene 内部标识了 documents（文档）所谓的 doc_id，它们是在 0 和 documents（文档）总数之间的一个整数。 这些 documents（文档）用于Lucene的内部API之间的通信：例如，使用 match 查询搜索 term 时会生成doc id的迭代器，然后使用这些 documents（文档）来检索规范的值以计算这些 documents（文档）的得分。实现此规范查找的方法是为每个 documents（文档）保留一个字节，然后通过读取索引中的 doc_id 字节来检索给定 documents（文档）的 id 的取值集合。虽然这是非常有效的，并且可以帮助 Lucene 快速访问每个 documents（文档）的标准值，但这样做的缺点是没有值的文档也需要一个字节的存储空间。

实际上，这意味着如果一个索引具有M个文档，则规范将需要每个字段M个字节的存储空间，即使只出现在索引文档的一小部分中的字段也是如此。虽然文档取值稍微复杂一些，因为 doc值 有多种方式，但是可以根据字段的类型和字段存储的实际数据进行编码，问题是非常相似的。如果想了解 fielddata，在 _Elasticsearch_ 2.0 之前的版本使用，之后替换成了 doc values，同样收到这个问题的影响，但是 fielddata 只是在内存占用上有影响，没有明确的具体化到磁盘。

请注意，尽管稀疏性最显着的影响是存储要求，但它也对索引速度和搜索速度有影响，因为这些字节对于没有字段的文档仍然需要在索引时写入并且在搜索时跳过。

索引中少数稀疏字段是完全正确的。 但请注意，如果稀疏性成为规则而不是异常，那么索引将不会如此有效。

这一部分主要集中在规范和 doc 值上，因为这些是影响最小两大特征。稀疏性也影响反向索引的效率（用于索引 _text / keyword_ 字段）和维度点（用于索引 geo_point 和数字），但程度较小。

以下是一些可以帮助避免稀疏性的建议：

### 避免将不相关的数据放在同一个索引中

您应避免将具有完全不同结构的 _documents（文档）_放入同一索引中，以避免稀疏。将这些文件放在不同的索引中往往更好，您也可以考虑为这些较小的索引提供更少的碎片，因为它们整体上将包含更少的文档。

请注意，此建议不适用于您需要使用文档之间的_parent / child_ 关系的情况，因为该功能仅在同一索引中的文档支持。

### 统一文档结构

即使你真的需要将不同类型的文档放在同一个索引中，也有机会减少稀疏性。 例如，如果索引中的所有文档都有一个 timestamp 字段，但有些则将其称为 timestamp，而另一些则将其称为“create_date”，那么对它重命名，以便所有文档具有相同数据的相同字段名称。

### 避免多类型（types）

Types（类型）可能听起来像是在单个索引中存储多个租户的好方法。 它们不是：给定类型将所有内容存储在单个索引中，在单个索引中具有不同字段的多个类型也将由于如上所述的稀疏性而导致问题。 如果您的类型没有非常相似的映射，您可能需要考虑将它们移动到专用索引。

### 在稀疏字段上禁用** `norms`** 和 doc_values

如果上述的一些建议不适用你的情况，你需要检查是否在稀疏字段确实需要 `norms` `和` `doc_values。如果在字段上不需要生成分数，则可以禁用 `norms` ，对于仅用于过滤的字段，这通常是正确的。对于既不用于排序也不用于聚合的字段，可以禁用doc_values。请注意，由于这些参数无法在实时索引中更改，因此您不要轻率做决定，因此如果您需要 ``norms` `或 doc_values，则必须重建索引。`