From 2cfea9e4680a1b2a60bb9df20ebd14ccb98a5841 Mon Sep 17 00:00:00 2001 From: "ievgen.degtiarenko" Date: Mon, 31 Mar 2025 15:18:24 +0200 Subject: [PATCH] Speedup field exists check --- .../xpack/esql/stats/SearchContextStats.java | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/SearchContextStats.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/SearchContextStats.java index 1f895c43f5dde..9bb230c72bb0d 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/SearchContextStats.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/SearchContextStats.java @@ -80,11 +80,6 @@ private SearchContextStats(List contexts) { assert contexts != null && contexts.isEmpty() == false; } - public boolean exists(String field) { - var stat = cache.computeIfAbsent(field, this::makeFieldStats); - return stat.config.exists; - } - private FieldStats makeFieldStats(String field) { var stat = new FieldStats(); stat.config = makeFieldConfig(field); @@ -123,19 +118,30 @@ private FieldConfig makeFieldConfig(String field) { } } + private boolean fastNoCacheFieldExists(String field) { + for (SearchExecutionContext context : contexts) { + if (context.isFieldMapped(field)) { + return true; + } + } + return false; + } + + public boolean exists(String field) { + var stat = cache.get(field); + return stat != null ? stat.config.exists : fastNoCacheFieldExists(field); + } + public boolean isIndexed(String field) { - var stat = cache.computeIfAbsent(field, this::makeFieldStats); - return stat.config.indexed; + return cache.computeIfAbsent(field, this::makeFieldStats).config.indexed; } public boolean hasDocValues(String field) { - var stat = cache.computeIfAbsent(field, this::makeFieldStats); - return stat.config.hasDocValues; + return cache.computeIfAbsent(field, this::makeFieldStats).config.hasDocValues; } public boolean hasExactSubfield(String field) { - var stat = cache.computeIfAbsent(field, this::makeFieldStats); - return stat.config.hasExactSubfield; + return cache.computeIfAbsent(field, this::makeFieldStats).config.hasExactSubfield; } public long count() { @@ -218,7 +224,7 @@ public boolean isSingleValue(String field) { var stat = cache.computeIfAbsent(field, this::makeFieldStats); if (stat.singleValue == null) { // there's no such field so no need to worry about multi-value fields - if (exists(field) == false) { + if (stat.config.exists == false) { stat.singleValue = true; } else { // fields are MV per default