diff --git a/src/main/java/org/folio/search/cql/builders/AllTermQueryBuilder.java b/src/main/java/org/folio/search/cql/builders/AllTermQueryBuilder.java index 5b02fc5d0..33d5734e5 100644 --- a/src/main/java/org/folio/search/cql/builders/AllTermQueryBuilder.java +++ b/src/main/java/org/folio/search/cql/builders/AllTermQueryBuilder.java @@ -14,20 +14,19 @@ @Component public class AllTermQueryBuilder extends FulltextQueryBuilder { + private static final String WHITE_SPACE = "\\s+"; + @Override public QueryBuilder getQuery(Object term, String resource, String... fields) { if (term instanceof String) { var stringTerm = (String) term; - var terms = stringTerm.split("\\s+"); + var terms = stringTerm.split(WHITE_SPACE); + if (terms.length == 1) { return getMultiMatchQuery(terms[0], fields); + } else { + return getBoolQuery(terms, fields); } - - var boolQuery = boolQuery(); - for (var singleTerm : terms) { - boolQuery.must(getMultiMatchQuery(singleTerm, fields)); - } - return boolQuery; } return getMultiMatchQuery(term, fields); @@ -51,4 +50,12 @@ public Set getSupportedComparators() { private QueryBuilder getMultiMatchQuery(Object term, String... fieldNames) { return multiMatchQuery(term, fieldNames).operator(AND).type(CROSS_FIELDS); } + + private QueryBuilder getBoolQuery(String[] terms, String... fieldNames) { + var boolQuery = boolQuery(); + for (var singleTerm : terms) { + boolQuery.must(getMultiMatchQuery(singleTerm, fieldNames)); + } + return boolQuery; + } } diff --git a/src/main/resources/elasticsearch/index/authority.json b/src/main/resources/elasticsearch/index/authority.json index a81ad4f54..ee0f2d16e 100644 --- a/src/main/resources/elasticsearch/index/authority.json +++ b/src/main/resources/elasticsearch/index/authority.json @@ -23,9 +23,19 @@ "source_analyzer": { "tokenizer": "icu_tokenizer", "filter": [ "folio_word_delimiter_graph", "icu_folding" ], + "char_filter": [ "authority_char_filter" ], "type": "custom" } }, - "tokenizers": { } + "tokenizers": { }, + "char_filter": { + "authority_char_filter": { + "type": "mapping", + "mappings": [ + "& => and", + ": => \\s+" + ] + } + } } } diff --git a/src/main/resources/elasticsearch/index/instance.json b/src/main/resources/elasticsearch/index/instance.json index 12cc15e98..91860b9a6 100644 --- a/src/main/resources/elasticsearch/index/instance.json +++ b/src/main/resources/elasticsearch/index/instance.json @@ -31,9 +31,19 @@ "source_analyzer": { "tokenizer": "icu_tokenizer", "filter": [ "folio_word_delimiter_graph", "icu_folding" ], + "char_filter": [ "instance_char_filter" ], "type": "custom" } }, - "tokenizers": { } + "tokenizers": { }, + "char_filter": { + "instance_char_filter": { + "type": "mapping", + "mappings": [ + "& => and", + ": => \\s+" + ] + } + } } } diff --git a/src/test/java/org/folio/search/controller/SearchInstanceIT.java b/src/test/java/org/folio/search/controller/SearchInstanceIT.java index 415e8efdf..481511787 100644 --- a/src/test/java/org/folio/search/controller/SearchInstanceIT.java +++ b/src/test/java/org/folio/search/controller/SearchInstanceIT.java @@ -286,7 +286,9 @@ private static Stream testDataProvider() { arguments("holdingsIdentifiers all {value}", "e3ff6133-b9a2-4d4c-a1c9-dc1867d4df19"), //search by multiple different parameters - arguments("(keyword all {value})", "wolves matthew 9781609383657") + arguments("(keyword all {value})", "wolves matthew 9781609383657"), + arguments("(keyword all {value})", "A semantic web primer & wolves"), + arguments("(title all {value})", "A semantic web primer : 0747-0850") ); } } diff --git a/src/test/resources/samples/semantic-web-primer/instance.json b/src/test/resources/samples/semantic-web-primer/instance.json index 15a7066b8..000853e79 100644 --- a/src/test/resources/samples/semantic-web-primer/instance.json +++ b/src/test/resources/samples/semantic-web-primer/instance.json @@ -2,7 +2,7 @@ "id": "5bf370e0-8cca-4d9c-82e4-5170ab2a0a39", "hrid": "inst000000000022", "source": "FOLIO", - "title": "A semantic web primer 0747-0850 wolves", + "title": "A semantic web primer :0747-0850 & wolves", "indexTitle": "Semantic web primer", "alternativeTitles": [ {