Skip to content

Commit

Permalink
Correctly set search quote analyzer for keyword fields (#68315)
Browse files Browse the repository at this point in the history
Keyword fields with split_queries_on_whitespace=true were also setting
whitespace analyzers to be used for quoted queries. Instead, keyword
fields should always set their searchQuoteAnalyzer to be the same as the
index-time normalizer.

Fixes #68313
  • Loading branch information
romseygeek committed Feb 2, 2021
1 parent 8849a18 commit 439cdbc
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,23 +144,23 @@ protected List<Parameter<?>> getParameters() {
private KeywordFieldType buildFieldType(ContentPath contentPath, FieldType fieldType) {
NamedAnalyzer normalizer = Lucene.KEYWORD_ANALYZER;
NamedAnalyzer searchAnalyzer = Lucene.KEYWORD_ANALYZER;
NamedAnalyzer quoteAnalyzer = Lucene.KEYWORD_ANALYZER;
String normalizerName = this.normalizer.getValue();
if (Objects.equals(normalizerName, "default") == false) {
assert indexAnalyzers != null;
normalizer = indexAnalyzers.getNormalizer(normalizerName);
if (normalizer == null) {
throw new MapperParsingException("normalizer [" + normalizerName + "] not found for field [" + name + "]");
}
searchAnalyzer = quoteAnalyzer = normalizer;
if (splitQueriesOnWhitespace.getValue()) {
searchAnalyzer = indexAnalyzers.getWhitespaceNormalizer(normalizerName);
} else {
searchAnalyzer = normalizer;
}
}
else if (splitQueriesOnWhitespace.getValue()) {
searchAnalyzer = Lucene.WHITESPACE_ANALYZER;
}
return new KeywordFieldType(buildFullName(contentPath), fieldType, normalizer, searchAnalyzer, this);
return new KeywordFieldType(buildFullName(contentPath), fieldType, normalizer, searchAnalyzer, quoteAnalyzer, this);
}

@Override
Expand All @@ -184,12 +184,13 @@ public static final class KeywordFieldType extends StringFieldType {
private final NamedAnalyzer normalizer;

public KeywordFieldType(String name, FieldType fieldType,
NamedAnalyzer normalizer, NamedAnalyzer searchAnalyzer, Builder builder) {
NamedAnalyzer normalizer, NamedAnalyzer searchAnalyzer, NamedAnalyzer quoteAnalyzer,
Builder builder) {
super(name,
fieldType.indexOptions() != IndexOptions.NONE,
fieldType.stored(),
builder.hasDocValues.getValue(),
new TextSearchInfo(fieldType, builder.similarity.getValue(), searchAnalyzer, searchAnalyzer),
new TextSearchInfo(fieldType, builder.similarity.getValue(), searchAnalyzer, quoteAnalyzer),
builder.meta.getValue());
setEagerGlobalOrdinals(builder.eagerGlobalOrdinals.getValue());
setBoost(builder.boost.getValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,8 @@ public void testSplitQueriesOnWhitespace() throws IOException {
ft.getTextSearchInfo().getSearchAnalyzer().analyzer().tokenStream("", "Hello World"),
new String[] { "hello", "world" }
);
Analyzer q = ft.getTextSearchInfo().getSearchQuoteAnalyzer();
assertTokenStreamContents(q.tokenStream("", "Hello World"), new String[] { "hello world" });

mapperService = createMapperService(mapping(b -> {
b.startObject("field").field("type", "keyword").field("split_queries_on_whitespace", true).endObject();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ protected void initializeAdditionalMappings(MapperService mapperService) throws
.field("type", "text")
.startObject("index_prefixes").endObject()
.endObject()
.startObject("ww_keyword")
.field("type", "keyword")
.field("split_queries_on_whitespace", true)
.endObject()
.endObject().endObject().endObject();

mapperService.merge("_doc",
Expand Down Expand Up @@ -1658,4 +1662,12 @@ private void assertQueryCachability(QueryStringQueryBuilder qb, boolean cachingE
assertEquals("query should " + (cachingExpected ? "" : "not") + " be cacheable: " + qb.toString(), cachingExpected,
context.isCacheable());
}

public void testWhitespaceKeywordQueries() throws IOException {
String query = "\"query with spaces\"";
QueryStringQueryBuilder b = new QueryStringQueryBuilder(query);
b.field("ww_keyword");
Query q = b.doToQuery(createSearchExecutionContext());
assertEquals(new TermQuery(new Term("ww_keyword", "query with spaces")), q);
}
}

0 comments on commit 439cdbc

Please sign in to comment.