Fix EuiSearchBar negated multi-value filter excluding only one value#9783
Fix EuiSearchBar negated multi-value filter excluding only one value#9783gunjanjaswal wants to merge 3 commits into
Conversation
|
💚 CLA has been signed |
|
👋 Since this is a community submitted pull request, a Buildkite build has not been started automatically. Would an Elastic organization member please verify the contents of this pull request and kick off a build manually? |
|
buildkite test this |
There was a problem hiding this comment.
Pull request overview
Fixes a logic bug in EuiSearchBar’s in-memory filtering (executeAst) where negated multi-value field clauses (e.g. -name:(john or doe)) incorrectly allowed items that should be excluded. The change aligns the implementation with De Morgan’s law by negating the aggregated positive match instead of negating per-value matches.
Changes:
- Updated
fieldClauseMatcherto compute a single “positive hit” for array values and then negate it formust_notclauses. - Added a Jest test covering negated multi-value field clauses to prevent regressions.
- Added a changelog entry documenting the bug fix.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| packages/eui/src/components/search_bar/query/execute_ast.ts | Fixes must_not + multi-value matching by negating the aggregate result instead of per-element negation. |
| packages/eui/src/components/search_bar/query/execute_ast.test.ts | Adds regression test for -field:(a or b) behavior. |
| packages/eui/changelogs/upcoming/9783.md | Notes the bug fix in the upcoming changelog. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@gunjanjaswal before we proceed with the review of your PR, could you sign CLA? |
I have signed the same. |
💚 Build Succeeded
History
|
💚 Build Succeeded
History
|
weronikaolejniczak
left a comment
There was a problem hiding this comment.
The fix looks great! Thank you for contributing @gunjanjaswal 🙏🏻 I tested in EUI, there's no regression.
Please do not rebase your branch onto main unless there are merge conflicts needed to be solved.
We will merge and release this fix whenever possible. We try to scope our releases down so it may take a while. I'd also like to run tests against Kibana to make sure we're not breaking any expected behavior.
Summary
What: Fixes
EuiSearchBar/executeAstreturning items that a negated multi-value field clause should exclude.Why: A query like
-name:(john or doe)parses toAST.Field.mustNot.eq('name', ['john', 'doe']).fieldClauseMatchernegated the operator per element and then combined the results with.some, computing(name !== 'john') OR (name !== 'doe'). By De Morgan,NOT (a OR b)must be(NOT a) AND (NOT b), so the code used the wrong quantifier and kept rows it should have hidden.Concrete repro: filtering
[{name:'john'},{name:'doe'},{name:'foo'}]with-name:(john or doe)returned all three rows instead of justfoo. The scalar path (-name:john) and the positive-array path (name:(a or b)) were already correct; only must_not combined with an array value was wrong.How: Compute the positive match first, then negate the aggregate result for must_not clauses (
isMust ? positiveHit : !positiveHit) instead of negating each element. Scalar and positive-array behavior is unchanged.API Changes
Screenshots
Not applicable. This is a logic-only fix to the in-memory filter with no visual change.
Impact Assessment
Impact level: 🟢 Low
Release Readiness
Documentation(no doc change)Figma(not applicable)Migration guide(bug fix, no migration)Adoption plan(not a feature)QA instructions for reviewer
EuiSearchBar/ in-memory table demo, or callexecuteAstdirectly.john,doe,foowith-name:(john or doe)and confirm onlyfooremains (before this PR all three remained).-name:john,name:(a or b), and single positive clauses are unchanged.Checklist before marking Ready for Review
QA: light/dark, mobile, browsers, keyboard, screen reader(logic-only, no UI change)QA: CodeSandbox / KibanaQA: docs changesBreaking changes(none)