From f322f537e41273fd33eb06752c5adcfa5850323f Mon Sep 17 00:00:00 2001 From: Adrien Grand Date: Fri, 21 Apr 2017 10:32:33 +0200 Subject: [PATCH] Speed up parsing of large `terms` queries. (#24210) The addition of the normalization feature on keywords slowed down the parsing of large `terms` queries since all terms now have to go through normalization. However this can be avoided in the default case that the analyzer is a `keyword` analyzer since all that normalization will do is a UTF8 conversion. Using `Analyzer.normalize` for that is a bit overkill and could be skipped. --- .../elasticsearch/index/mapper/KeywordFieldMapper.java | 9 +++++++++ .../index/mapper/KeywordFieldTypeTests.java | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/core/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java index f988a68d5efcc..3e09199abca0c 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java @@ -236,6 +236,15 @@ public Object valueForDisplay(Object value) { @Override protected BytesRef indexedValueForSearch(Object value) { + if (searchAnalyzer() == Lucene.KEYWORD_ANALYZER) { + // keyword analyzer with the default attribute source which encodes terms using UTF8 + // in that case we skip normalization, which may be slow if there many terms need to + // parse (eg. large terms query) since Analyzer.normalize involves things like creating + // attributes through reflection + // This if statement will be used whenever a normalizer is NOT configured + return super.indexedValueForSearch(value); + } + if (value == null) { return null; } diff --git a/core/src/test/java/org/elasticsearch/index/mapper/KeywordFieldTypeTests.java b/core/src/test/java/org/elasticsearch/index/mapper/KeywordFieldTypeTests.java index 5c418b7ce265e..809ceb5831004 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/KeywordFieldTypeTests.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/KeywordFieldTypeTests.java @@ -150,4 +150,13 @@ public void testFuzzyQuery() { () -> ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true)); assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); } + + public void testNormalizeQueries() { + MappedFieldType ft = createDefaultFieldType(); + ft.setName("field"); + ft.setSearchAnalyzer(Lucene.KEYWORD_ANALYZER); + assertEquals(new TermQuery(new Term("field", new BytesRef("FOO"))), ft.termQuery("FOO", null)); + ft.setSearchAnalyzer(Lucene.STANDARD_ANALYZER); + assertEquals(new TermQuery(new Term("field", new BytesRef("foo"))), ft.termQuery("FOO", null)); + } }