From 254a7f10d2fa9c5114cebd29f07c656e2b54f72e Mon Sep 17 00:00:00 2001 From: kert Date: Thu, 24 Sep 2026 20:02:15 -0400 Subject: [PATCH] =?UTF-8?q?fix(llm):=20nest=20the=20theme=20$or=20under=20?= =?UTF-8?q?$and=20with=20the=20field=20filters=20=E2=80=94=20langchain-pos?= =?UTF-8?q?tgres=20rejects=20an=20operator=20beside=20field=20keys=20at=20?= =?UTF-8?q?the=20top=20level=20(500=20on=20/search=3Ftheme=3D)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/llm/search.py | 8 +++++++- tests/llm/test_search.py | 20 +++++++++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/llm/search.py b/src/llm/search.py index cd8cc6a..7ffb76a 100644 --- a/src/llm/search.py +++ b/src/llm/search.py @@ -78,7 +78,13 @@ def _store_filter(filters: dict[str, str]) -> dict[str, Any]: } theme = str(filters.get("theme") or "") if theme: - out["$or"] = [{f"theme_{i}": theme} for i in range(1, 4)] + # langchain-postgres accepts either a mapping of field keys or a + # single operator at the top level, never both — so field + # conditions and the theme $or nest under one $and. + theme_or = {"$or": [{f"theme_{i}": theme} for i in range(1, 4)]} + if out: + return {"$and": [*({k: v} for k, v in out.items()), theme_or]} + return theme_or return out diff --git a/tests/llm/test_search.py b/tests/llm/test_search.py index 78a7a0b..d0d3b2d 100644 --- a/tests/llm/test_search.py +++ b/tests/llm/test_search.py @@ -393,10 +393,16 @@ class TestThemeFilter: assert _theme_ok({}, "") def test_theme_is_pushed_down_as_an_or_of_rank_keys(self): - out = _store_filter({"theme": "telehealth", "doctype": "manual"}) - assert out["doctype"] == "manual" - assert out["$or"] == [ - {"theme_1": "telehealth"}, - {"theme_2": "telehealth"}, - {"theme_3": "telehealth"}, - ] + theme_or = { + "$or": [ + {"theme_1": "telehealth"}, + {"theme_2": "telehealth"}, + {"theme_3": "telehealth"}, + ] + } + # field keys and an operator never share the top level (the store + # rejects that): fields and the theme $or nest under one $and + assert _store_filter({"theme": "telehealth", "doctype": "manual"}) == { + "$and": [{"doctype": "manual"}, theme_or] + } + assert _store_filter({"theme": "telehealth"}) == theme_or