Skip to content

Commit

Permalink
Add support for quoted default search term values
Browse files Browse the repository at this point in the history
  • Loading branch information
danotorrey committed Feb 7, 2025
1 parent 5fbdb53 commit d2497f5
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,16 @@ public class SearchQueryParser {
private static final Splitter FIELD_VALUE_SPLITTER = Splitter.on(":").limit(2).omitEmptyStrings().trimResults();
private static final Splitter VALUE_SPLITTER = Splitter.on(",").omitEmptyStrings().trimResults();

// Pattern to split a search query into individual parsable elements terms.
private static final String TERM_SPLIT_PATTERN =
"(\\S+:(=|=~|<|<=|>|>=)?'(?:[^'\\\\]|\\\\.)*')|" + // Field-specific terms with single-quotes: title:'value'
"(\\S+:(=|=~|<|<=|>|>=)?\"(?:[^\"\\\\]|\\\\.)*\")|" + // Field-specific terms with double-quotes title:"value"
"['\"][^\\\\]*?(?:\\\\.[^\\\\]*)*?['\"]|" + // Single quoted value: "value one"
"\\S+:(=|=~|<|<=|>|>=)?\\S+|" + // Field-specific terms without quotes title:value
"\\S+"; // Split the words of any other string value

// This needs to be updated if more operators are added
private static final Pattern QUERY_SPLITTER_PATTERN = Pattern.compile("(\\S+:(=|=~|<|<=|>|>=)?'(?:[^'\\\\]|\\\\.)*')|(\\S+:(=|=~|<|<=|>|>=)?\"(?:[^\"\\\\]|\\\\.)*\")|\\S+|\\S+:(=|=~|<|<=|>|>=)?\\S+");
private static final Pattern QUERY_SPLITTER_PATTERN = Pattern.compile(TERM_SPLIT_PATTERN);
private static final String INVALID_ENTRY_MESSAGE = "Chunk [%s] is not a valid entry";
private static final String QUOTE_REPLACE_REGEX = "^[\"']|[\"']$";
public static final SearchQueryOperator DEFAULT_STRING_OPERATOR = SearchQueryOperators.REGEXP;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;

import static org.assertj.core.api.Assertions.assertThat;
Expand Down Expand Up @@ -293,6 +294,31 @@ void emptyFieldPrefixDoesNotChangeDefaultBehavior() {
assertThat(searchQuery.hasDisallowedKeys()).isFalse();
}

@Test
void unquotedEmptyFieldPrefixSingleSearchTerm() {
final SearchQueryParser parser = new SearchQueryParser("name", Set.of(), "");
// Verify unquoted term is split into two search values.
final SearchQuery searchQuery = parser.parse("Bobby testerson");
final Multimap<String, SearchQueryParser.FieldValue> queryMap = searchQuery.getQueryMap();
assertThat(queryMap.keySet().size()).isEqualTo(1);
final Collection<SearchQueryParser.FieldValue> values = queryMap.get("name");
assertThat(values.size()).isEqualTo(2);
assertThat(values).contains(new SearchQueryParser.FieldValue("Bobby", false));
assertThat(values).contains(new SearchQueryParser.FieldValue("testerson", false));
}

@Test
void quotedEmptyFieldPrefixSingleSearchTerm() {
final SearchQueryParser parser = new SearchQueryParser("name", Set.of(), "");
// Verify quoted term is maintained as a single search value.
final SearchQuery searchQuery = parser.parse("\"Bobby testerson\"");
final Multimap<String, SearchQueryParser.FieldValue> queryMap = searchQuery.getQueryMap();
assertThat(queryMap.keySet().size()).isEqualTo(1);
final Collection<SearchQueryParser.FieldValue> values = queryMap.get("name");
assertThat(values.size()).isEqualTo(1);
assertThat(values).containsOnly(new SearchQueryParser.FieldValue("Bobby testerson", false));
}

@Test
void booleanValuesSupported() {
final SearchQueryParser parser = new SearchQueryParser("name",
Expand Down

0 comments on commit d2497f5

Please sign in to comment.