用于查询和排序的多字段与字段数据
Multi-field vs. fielddata for querying and sorting
我有一个使用 Elasticsearch 6 的简单“人”数据库,它看起来基本上是这样的:
id | firstName | lastName
-------------------------
1 | Tim | Berners-Lee
2 | Linus | Torvalds
3 | Noam | Chomsky
我想按 lastName
查询和排序(and/or 按 firstName
- 取决于用户输入)。
现在我找到了 2 个似乎有效的解决方案,但我不确定哪个“正确”(或“更好”)以及原因:
多字段:"type": "text", "fields": { "raw": { "type": "keyword" } }
:我可以用lastName
查询,用lastName.raw
排序。
fielddata: "type": "text", "fielddata": true
: 这里我可以使用lastName
.
进行查询和排序
但我完全不确定为什么我应该选择一个而不是另一个,以及这个选择有什么影响。
希望以下几点能帮助您根据实际用例做出决定。
多字段
它的用途 - 存储具有不同分析器的单个字段。正如您使用的 text
和 keyword
它没有任何特殊的缓存。
字段数据
它的目的 - 在 aggregation/sorting 期间更快地访问。它将所有数据加载到字段缓存中。
虽然您可以使用它来实现您的需求,但它很昂贵。
- 加载字段数据很昂贵
- 加载后,它会在 Lucene 段的生命周期内保持不变
- 由于你的字段是文本,它会占用大量的堆space。
但是您可以使用 fielddata_frequency_filter
控制加载到内存中的术语数
并且您在 text
字段上进行排序。文档中的建议是
Instead, you should have a text field for full text searches, and an unanalyzed keyword field with doc_values enabled for aggregations
因此,您需要根据数据大小、数据访问模式、服务器成本进行选择,以防您有更多数据并计划使用 field data
我有一个使用 Elasticsearch 6 的简单“人”数据库,它看起来基本上是这样的:
id | firstName | lastName
-------------------------
1 | Tim | Berners-Lee
2 | Linus | Torvalds
3 | Noam | Chomsky
我想按 lastName
查询和排序(and/or 按 firstName
- 取决于用户输入)。
现在我找到了 2 个似乎有效的解决方案,但我不确定哪个“正确”(或“更好”)以及原因:
多字段:
"type": "text", "fields": { "raw": { "type": "keyword" } }
:我可以用lastName
查询,用lastName.raw
排序。fielddata:
进行查询和排序"type": "text", "fielddata": true
: 这里我可以使用lastName
.
但我完全不确定为什么我应该选择一个而不是另一个,以及这个选择有什么影响。
希望以下几点能帮助您根据实际用例做出决定。
多字段
它的用途 - 存储具有不同分析器的单个字段。正如您使用的
text
和keyword
它没有任何特殊的缓存。
字段数据
它的目的 - 在 aggregation/sorting 期间更快地访问。它将所有数据加载到字段缓存中。 虽然您可以使用它来实现您的需求,但它很昂贵。
- 加载字段数据很昂贵
- 加载后,它会在 Lucene 段的生命周期内保持不变
- 由于你的字段是文本,它会占用大量的堆space。
但是您可以使用 fielddata_frequency_filter
并且您在 text
字段上进行排序。文档中的建议是
Instead, you should have a text field for full text searches, and an unanalyzed keyword field with doc_values enabled for aggregations
因此,您需要根据数据大小、数据访问模式、服务器成本进行选择,以防您有更多数据并计划使用 field data