索引排序
edit索引排序
edit在Elasticsearch中创建新索引时,可以配置每个分片内的段如何排序。默认情况下,Lucene不应用任何排序。index.sort.*
设置定义了应使用哪些字段对每个段内的文档进行排序。
允许对包含嵌套对象的映射应用索引排序,只要index.sort.*
设置中不包含嵌套字段。
例如,以下示例展示了如何在一个字段上定义排序:
PUT my-index-000001 { "settings": { "index": { "sort.field": "date", "sort.order": "desc" } }, "mappings": { "properties": { "date": { "type": "date" } } } }
也可以通过多个字段对索引进行排序:
PUT my-index-000001 { "settings": { "index": { "sort.field": [ "username", "date" ], "sort.order": [ "asc", "desc" ] } }, "mappings": { "properties": { "username": { "type": "keyword", "doc_values": true }, "date": { "type": "date" } } } }
索引排序支持以下设置:
-
index.sort.field
-
用于对索引进行排序的字段列表。
仅允许使用具有
doc_values
的boolean
、numeric
、date
和keyword
字段。 -
index.sort.order
-
每个字段要使用的排序顺序。 order 选项可以具有以下值:
-
asc
: 升序 -
desc
: 降序。
-
-
index.sort.mode
-
Elasticsearch 支持对多值字段进行排序。 mode 选项控制选择哪个值来对文档进行排序。 mode 选项可以具有以下值:
-
min
: 选择最小值。 -
max
: 选择最大值。
-
-
index.sort.missing
-
missing 参数指定如何处理缺少该字段的文档。 missing 值可以具有以下值:
-
_last
: 没有该字段值的文档将排在最后。 -
_first
: 没有该字段值的文档将排在最前。
-
索引排序只能在索引创建时定义一次。不允许在现有索引上添加或更新排序。索引排序还会在索引吞吐量方面产生成本,因为文档必须在刷新和合并时进行排序。在激活此功能之前,您应该测试其对应用程序的影响。
搜索请求的提前终止
edit默认情况下,Elasticsearch 中的搜索请求必须访问与查询匹配的每个文档,以检索按指定排序排序的顶部文档。 尽管当索引排序和搜索排序相同时,可以限制每个分段应访问的文档数量,以检索全局排名前 N 的文档。 例如,假设我们有一个按时间戳字段排序的事件索引:
PUT events { "settings": { "index": { "sort.field": "timestamp", "sort.order": "desc" } }, "mappings": { "properties": { "timestamp": { "type": "date" } } } }
您可以搜索最近的10个事件,使用:
GET /events/_search { "size": 10, "sort": [ { "timestamp": "desc" } ] }
Elasticsearch 会检测到每个分段的顶部文档已经在索引中排序,并且只会比较每个分段的第一个 N 个文档。 与查询匹配的其余文档会被收集起来以计算结果的总数,并构建聚合。
如果你只寻找最近的10个事件,并且对匹配查询的文档总数不感兴趣,你可以将track_total_hits
设置为false:
这次,Elasticsearch不会尝试计算文档的数量,并且一旦每个分段收集到N个文档,就能够终止查询。
聚合将收集所有匹配查询的文档,无论track_total_hits
的值如何
使用索引排序来加速连接
edit索引排序可以用于组织Lucene文档ID(不要与_id
混淆),以便使合取(a AND b AND …)更高效。为了提高效率,合取依赖于这样一个事实:如果任何子句不匹配,那么整个合取就不匹配。通过使用索引排序,我们可以将不匹配的文档放在一起,这将有助于高效地跳过不匹配合取的大范围文档ID。
这个技巧只适用于低基数字段。一个经验法则是,你应该首先对那些既具有低基数又经常用于过滤的字段进行排序。排序顺序(asc
或 desc
)并不重要,因为我们只关心将匹配相同子句的值放在一起。
例如,如果您正在为待售汽车建立索引,按燃油类型、车身类型、品牌、注册年份和最后按里程数排序可能会很有趣。