filter_by hangs indefinitely combining a range condition with an equality condition on two numeric fields inside a nested object[] {...} block (2+ array elements)
Title
filter_by hangs indefinitely combining a range condition with an equality condition on two numeric fields inside a nested object[] {...} block (2+ array elements)
Body
Description
When filtering a nested object[] field using the <parent>.{...} same-element syntax, a query that combines a range/inequality condition (>=, >, <, <=, [a..b]) on one numeric sibling field with an equality condition (:=) on another numeric sibling field hangs indefinitely (no response, no error, no timeout) — but only when the document has 2 or more elements in that nested array. The exact same filter on a document with a single array element returns instantly.
This reproduces with both int32[] and int64[] field types. It does not reproduce when one of the two conditions is on a string field (e.g. the worked example in the docs, name:=cheese && concentration:<50), which is presumably why this hasn't shown up in the documented examples — they only exercise the string+numeric combination.
Typesense Version
typesense/typesense:30.2 (Docker)
Schema
{
"name": "repro_test",
"enable_nested_fields": true,
"fields": [
{ "name": "title", "type": "string" },
{ "name": "financing_quotes", "type": "object[]" },
{ "name": "financing_quotes.monthly_payment_in_dollars", "type": "int64[]" },
{ "name": "financing_quotes.down_payment_amount_in_dollars", "type": "int64[]", "optional": true }
]
}Steps to Reproduce
- Create the collection above.
- Insert a document with one financing quote element:
{ "id": "t1", "title": "t", "financing_quotes": [ { "monthly_payment_in_dollars": 637 } ] }- Run:
GET /collections/repro_test/documents/search?q=*&query_by=title&filter_by=financing_quotes.{monthly_payment_in_dollars:>=150 %26%26 down_payment_amount_in_dollars:=2000}→ Returns instantly (≈2ms), as expected (no match, since down_payment_amount_in_dollars doesn't exist on this element).
- Insert a second document with two financing quote elements instead:
{
"id": "t3",
"title": "t",
"financing_quotes": [
{ "monthly_payment_in_dollars": 637 },
{ "monthly_payment_in_dollars": 595, "down_payment_amount_in_dollars": 2000 }
]
}- Run the exact same filter, scoped to this document:
GET /collections/repro_test/documents/search?q=*&query_by=title&filter_by=id:=t3 %26%26 financing_quotes.{monthly_payment_in_dollars:>=150 %26%26 down_payment_amount_in_dollars:=2000}→ Hangs indefinitely. No response within 6+ seconds (tested up to several minutes); the underlying engine appears to be in an infinite or extremely long-running loop. CPU usage on the typesense process spikes during this time.
Additional findings from isolating this
- Array length is the deciding factor, not field presence/absence, not the optional flag, not range width. A single-element array is always fast regardless of operator combination. Two or more elements + (range × equality) on numeric siblings always hangs, regardless of whether the field is present, absent, or
nullon either element, and regardless of how narrow the range is (evenmonthly_payment_in_dollars:[600..650]hangs). - An all-equality filter on the same 2-element document (
monthly_payment_in_dollars:=595 && down_payment_amount_in_dollars:=2000) is fast. - Dropping the
{...}same-element syntax entirely (financing_quotes.monthly_payment_in_dollars:>=150 && financing_quotes.down_payment_amount_in_dollars:=2000, independent top-level filters) is fast, but loses the same-element matching guarantee that{...}exists for. - This reproduces identically with
int32[]fields instead ofint64[]. - Casting one of the two fields to
string[]does not reliably avoid the bug — behavior was inconsistent across otherwise-identical schemas/values during testing, which suggests this isn't simply about numeric vs. string typing but something deeper/more unstable in the same-element matching code path for the all-numeric case.
Expected Behavior
The query in step 5 should return quickly (no match, or a match depending on intent) like every other variant of this filter does on a single-element array.
Impact
This makes the documented {...} nested-object-array filter syntax effectively unusable for any numeric-only multi-condition filter once a document's nested array has more than one element — which is the common case for use cases like multiple pricing/quote options, multiple locations, multiple variants, etc.
Possibly Related
- https://github.com/typesense/typesense/issues/2469 (similar symptom — combining
{...}with other top-level&&conditions is slow/hangs in v29 — but that issue's repro is a different shape; not certain this is the same root cause) - https://github.com/typesense/typesense/issues/2347 (closed — different scenario, deeply nested object-within-object fields, not applicable here since these are flat primitive sibling fields)
Source: typesense/typesense