Skip to content

MultiFieldQueryParser: default operator is not honored between term positions (#16443) - #16446

Open
OlivierJaquemet wants to merge 1 commit into
apache:mainfrom
OlivierJaquemet:fix-16443
Open

MultiFieldQueryParser: default operator is not honored between term positions (#16443)#16446
OlivierJaquemet wants to merge 1 commit into
apache:mainfrom
OlivierJaquemet:fix-16443

Conversation

@OlivierJaquemet

Copy link
Copy Markdown

Fixes #16443

Problem: MultiFieldQueryParser's javadoc promises that under AND_OPERATOR, "all the query's terms must appear, but it doesn't matter in what fields they appear." This only holds when each term reaches the parser as a separate grammar-level token (real whitespace, handled by QueryParser.jj's own Clause()/addClause() machinery). It doesn't hold when several terms are produced by the analyzer alone from a single piece of query text passed to one getFieldQuery(null, text, quoted) call — e.g. an escaped separator with no real whitespace, word decompounding, CJK segmentation, or synonym expansion. In that case, getMultiFieldQuery() always combines the per-position groups with Occur.SHOULD, ignoring the configured default operator entirely.

Example: with AND_OPERATOR and an analyzer that splits "colonBefore:colonAfter" (one escaped grammar token, no real whitespace) into two terms, MultiFieldQueryParser produces (field1:colonbefore field2:colonbefore) (field1:colonafter field2:colonafter) — no + at all, i.e. effectively OR — instead of the documented +(...) +(...).

Fix: getMultiFieldQuery is reused for two different things: combining fields for a single term (always SHOULD, correct) and combining term positions when maxTerms > 1 (should honor the default operator). This adds a dedicated getMultiTermPositionQuery step for the latter case, leaving getMultiFieldQuery itself untouched for its existing field-combination role:

- return getMultiFieldQuery(clauses);
+ return maxTerms > 1 ? getMultiTermPositionQuery(clauses) : getMultiFieldQuery(clauses);

Testing: added tests to TestMultiFieldQueryParser reproducing the analyzer-split-single-token case (OR and AND, with and without a per-field boost), using MockAnalyzer/MockTokenizer.SIMPLE so that specific input needs an analyzer that actually emits more than one token to exercise this path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MultiFieldQueryParser: default operator is not honored between term positions

1 participant