#2964·typesense

filter_by hangs indefinitely combining a range condition with an equality condition on two numeric fields inside a nested object[] {...} block (2+ array elements)

Author: dominioncfgCreated Jun 26, 2026Updated Sep 2, 2026
Labelsawaiting-reply

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

json
{
  "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

  1. Create the collection above.
  2. Insert a document with one financing quote element:
json
{ "id": "t1", "title": "t", "financing_quotes": [ { "monthly_payment_in_dollars": 637 } ] }
  1. 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).

  1. Insert a second document with two financing quote elements instead:
json
{
  "id": "t3",
  "title": "t",
  "financing_quotes": [
    { "monthly_payment_in_dollars": 637 },
    { "monthly_payment_in_dollars": 595, "down_payment_amount_in_dollars": 2000 }
  ]
}
  1. 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 null on either element, and regardless of how narrow the range is (even monthly_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 of int64[].
  • 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