Skip to content

Add ALL and ONE array filter operators for MongoDB and Postgres - #323

Open
lrathod wants to merge 1 commit into
hypertrace:mainfrom
lrathod:ASP-3008/array-match-all-one-operators
Open

Add ALL and ONE array filter operators for MongoDB and Postgres#323
lrathod wants to merge 1 commit into
hypertrace:mainfrom
lrathod:ASP-3008/array-match-all-one-operators

Conversation

@lrathod

@lrathod lrathod commented Aug 27, 2026

Copy link
Copy Markdown

Summary

Adds two new ArrayOperator values for filtering on array-valued attributes (ticket ASP-3008):

  • ALL — array attribute must contain every value specified in the filter
  • ONE — array attribute must contain exactly one element, and that element must be one of the specified values

MongoDB

  • ALL{"$expr": {"$setIsSubset": [<values>, {"$ifNull": ["$<arrayPath>", []]}]}} (set containment, null-safe)
  • ONE$and of $size == 1 and $in on $arrayElemAt [path, 0] (cardinality + membership)

Postgres

  • Native array columns (flat collections): ALLCOALESCE(col, ARRAY[]::type[]) @> ?; ONEarray_length(...) = 1 AND col && ?
  • JSONB array paths (nested documents): ALL(CASE WHEN jsonb_typeof(path) = 'array' THEN path ELSE '[]'::jsonb END) @> ?::jsonb; ONEjsonb_array_length(...) = 1 AND (path @> ?::jsonb OR ...) per value
  • SQL array type inferred from the constant values via PostgresDataType.fromJavaValue()

Design note

Both parsers require the inner RelationalExpression to carry a constant value list; a non-constant RHS throws UnsupportedOperationException. This is intentional — ALL/ONE are set-level operators, unlike ANY which supports arbitrary per-element sub-filters.

Test plan

  • 6 new unit tests in MongoArrayFilterParserTest (operator structure, $ifNull guards, single-value, non-constant RHS rejection, no double $expr wrapping)
  • 5 new unit tests in PostgresQueryParserTest (ALL/ONE × JSONB/native array, nested JSONB path)
  • 2 new parameterized integration tests in ArrayFiltersQueryIntegrationTest (Mongo + Postgres) with 3 new JSON fixtures — run in CI
  • :document-store:build (compile + unit tests + spotless) passes locally

Made with Cursor

Add two new ArrayOperator values for filtering on array-valued attributes:
- ALL: array attribute must contain every value specified in the filter
- ONE: array attribute must contain exactly one element, and that element
  must be one of the specified values

MongoDB: ALL uses $setIsSubset with an $ifNull guard; ONE combines
$size == 1 with $in on the first element via $arrayElemAt.

Postgres: native array columns use @> (ALL) and array_length + && (ONE);
JSONB array paths use jsonb_typeof-guarded @> containment and
jsonb_array_length respectively.

Both parsers require the inner filter to carry a constant value list;
non-constant RHS expressions throw UnsupportedOperationException since
these are set-level operators, not per-element predicates like ANY.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant