Context
When building attribute filters programmatically, it's common to collect conditions into a list and then wrap them in {"type": "and", "filters": [...]}. This works well for 2+ conditions, but requires special-casing for 0 and 1 conditions since ChromaDB rejects $and with a single entry.
This leads to boilerplate like:
if len(filters) == 0:
attributes_filter = None
elif len(filters) == 1:
attributes_filter = filters[0]
else:
attributes_filter = {"type": "and", "filters": filters}
It would be nice if raghilda could unwrap single-element logical nodes automatically during filter compilation (before emitting to the backend), so users could always write:
attributes_filter = {"type": "and", "filters": filters} if filters else None
Possible approach
In _emit_chroma_where (and similar emitters), if a logical node has exactly one child, emit the child directly instead of wrapping it in $and/$or. The DuckDB and OpenAI emitters may already handle this gracefully, so it might only need a ChromaDB-specific change.
Context
When building attribute filters programmatically, it's common to collect conditions into a list and then wrap them in
{"type": "and", "filters": [...]}. This works well for 2+ conditions, but requires special-casing for 0 and 1 conditions since ChromaDB rejects$andwith a single entry.This leads to boilerplate like:
It would be nice if raghilda could unwrap single-element logical nodes automatically during filter compilation (before emitting to the backend), so users could always write:
Possible approach
In
_emit_chroma_where(and similar emitters), if a logical node has exactly one child, emit the child directly instead of wrapping it in$and/$or. The DuckDB and OpenAI emitters may already handle this gracefully, so it might only need a ChromaDB-specific change.