Skip to content

Commit 9f1619d

Browse files
authored
Merge pull request #130 from BioPack-team/constraints-autogen
Disable attribute constraints generation during `transpiling` phase for now
2 parents 71a67a1 + 9ad6ec5 commit 9f1619d

3 files changed

Lines changed: 83 additions & 38 deletions

File tree

src/retriever/data_tiers/tier_1/elasticsearch/transpiler.py

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,53 @@ def process_qedge(self, qedge: QEdgeDict) -> list[ESFilterClause]:
137137
if (values := qedge.get(qfield))
138138
]
139139

140-
def generate_query_for_merged_edges(
141-
self, in_node: QNodeDict, edge: QEdgeDict, out_node: QNodeDict
140+
def generate_attribute_constraints(
141+
self,
142+
in_node: QNodeDict,
143+
edge: QEdgeDict,
144+
out_node: QNodeDict,
145+
query_kwargs: ESBooleanQuery,
146+
) -> ESBooleanQuery:
147+
"""Generate attribute constraints based on QNode/QEdge payload."""
148+
constraint_origins: list[AttributeOrigin] = ["edge", "subject", "object"]
149+
150+
all_must: list[AttributeFilterQuery] = []
151+
all_must_not: list[AttributeFilterQuery] = []
152+
153+
for origin in constraint_origins:
154+
entity = (
155+
edge
156+
if origin == "edge"
157+
else in_node
158+
if origin == "subject"
159+
else out_node
160+
)
161+
162+
if origin == "edge":
163+
constraints = entity.get("attribute_constraints", None)
164+
else:
165+
constraints = entity.get("constraints", None)
166+
167+
if constraints:
168+
must, must_not = process_attribute_constraints(constraints, origin)
169+
if must:
170+
all_must.extend(must)
171+
if must_not:
172+
all_must_not.extend(must_not)
173+
174+
if all_must:
175+
query_kwargs["must"] = all_must
176+
if all_must_not:
177+
query_kwargs["must_not"] = all_must_not
178+
179+
return query_kwargs
180+
181+
def generate_queries(
182+
self,
183+
in_node: QNodeDict,
184+
edge: QEdgeDict,
185+
out_node: QNodeDict,
186+
gen_attribute_constraints: bool = False, # disable attribute constraints for now
142187
) -> ESPayload:
143188
"""Generate query based on merged edges schema on Elasticsearch.
144189
@@ -185,37 +230,12 @@ def generate_query_for_merged_edges(
185230
query_kwargs["filter"].append(qualifier_terms)
186231

187232
# generate constraint terms for edges and associated nodes
188-
constraint_origins: list[AttributeOrigin] = ["edge", "subject", "object"]
189-
190-
all_must: list[AttributeFilterQuery] = []
191-
all_must_not: list[AttributeFilterQuery] = []
192-
193-
for origin in constraint_origins:
194-
entity = (
195-
edge
196-
if origin == "edge"
197-
else in_node
198-
if origin == "subject"
199-
else out_node
233+
# currently, this is DISABLED by default to favor post-processing
234+
if gen_attribute_constraints:
235+
query_kwargs = self.generate_attribute_constraints(
236+
in_node, edge, out_node, query_kwargs
200237
)
201238

202-
if origin == "edge":
203-
constraints = entity.get("attribute_constraints", None)
204-
else:
205-
constraints = entity.get("constraints", None)
206-
207-
if constraints:
208-
must, must_not = process_attribute_constraints(constraints, origin)
209-
if must:
210-
all_must.extend(must)
211-
if must_not:
212-
all_must_not.extend(must_not)
213-
214-
if all_must:
215-
query_kwargs["must"] = all_must
216-
if all_must_not:
217-
query_kwargs["must_not"] = all_must_not
218-
219239
return ESPayload(query=ESQueryContext(bool=ESBooleanQuery(**query_kwargs)))
220240

221241
@override
@@ -226,7 +246,7 @@ def convert_triple(self, qgraph: QueryGraphDict) -> ESPayload:
226246
raise ValueError("Query graph must contain exactly one edge.")
227247
in_node = qgraph["nodes"][edge["subject"]]
228248
out_node = qgraph["nodes"][edge["object"]]
229-
return self.generate_query_for_merged_edges(in_node, edge, out_node)
249+
return self.generate_queries(in_node, edge, out_node)
230250

231251
@override
232252
def convert_batch_triple(self, qgraphs: list[QueryGraphDict]) -> list[ESPayload]:

tests/data_tiers/tier_1/elasticsearch_tests/test_tier1_driver.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from retriever.data_tiers.tier_1.elasticsearch.types import ESPayload, ESEdge
1010
from payload.trapi_qgraphs import DINGO_QGRAPH, VALID_REGEX_QGRAPHS, INVALID_REGEX_QGRAPHS, ID_BYPASS_PAYLOAD
1111
from retriever.utils.redis import REDIS_CLIENT
12+
from test_tier1_transpiler import _convert_triple, _convert_batch_triple
1213

1314

1415
def esp(d: dict[str, Any]) -> ESPayload:
@@ -148,15 +149,15 @@ def assert_single_result(res, expected_result_num: int):
148149
def test_invalid_regex_qgraph(qgraph):
149150
transpiler = ElasticsearchTranspiler()
150151
with pytest.raises(ValueError):
151-
transpiler.convert_triple(qgraph)
152+
_convert_triple(transpiler, qgraph)
152153

153154

154155
@pytest.mark.usefixtures("mock_elasticsearch_config")
155156
@pytest.mark.asyncio
156157
async def test_valid_regex_query():
157158
transpiler = ElasticsearchTranspiler()
158159

159-
qgraphs_with_valid_regex = transpiler.convert_batch_triple(VALID_REGEX_QGRAPHS)
160+
qgraphs_with_valid_regex = _convert_batch_triple(transpiler, VALID_REGEX_QGRAPHS)
160161

161162
driver: driver_mod.ElasticSearchDriver = driver_mod.ElasticSearchDriver()
162163

@@ -211,7 +212,7 @@ async def test_metadata_retrieval():
211212
)
212213
async def test_end_to_end(qgraph, expected_hits):
213214
transpiler = ElasticsearchTranspiler()
214-
payload = transpiler.convert_triple(qgraph)
215+
payload = _convert_triple(transpiler, qgraph)
215216

216217
driver: driver_mod.ElasticSearchDriver = driver_mod.ElasticSearchDriver()
217218

tests/data_tiers/tier_1/elasticsearch_tests/test_tier1_transpiler.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,26 @@ def es_transpiler() -> ElasticsearchTranspiler:
3333
return ElasticsearchTranspiler()
3434

3535

36+
def _convert_triple(
37+
es_transpiler: ElasticsearchTranspiler,
38+
qgraph: QueryGraphDict,
39+
) -> ESPayload:
40+
"""Wrapper for convert_triple so attribute constraints are generated by default."""
41+
edge = next(iter(qgraph["edges"].values()), None)
42+
if edge is None:
43+
raise ValueError("Query graph must contain exactly one edge.")
44+
in_node = qgraph["nodes"][edge["subject"]]
45+
out_node = qgraph["nodes"][edge["object"]]
46+
return es_transpiler.generate_queries(in_node, edge, out_node, gen_attribute_constraints=True)
47+
48+
49+
def _convert_batch_triple(
50+
es_transpiler: ElasticsearchTranspiler,
51+
qgraphs: list[QueryGraphDict]
52+
) -> list[ESPayload]:
53+
return [_convert_triple(es_transpiler, qgraph) for qgraph in qgraphs]
54+
55+
3656
def check_list_fields(reference: list, against: list):
3757
for ref, ag in zip(reference, against):
3858
if ref.startswith("biolink:"):
@@ -205,7 +225,9 @@ def add_to_required_fields(_field: str, _side: side_type):
205225
def test_bypass_payload(
206226
es_transpiler: ElasticsearchTranspiler
207227
) -> None:
208-
generated_payload = es_transpiler.convert_triple(ID_BYPASS_PAYLOAD)
228+
# generated_payload = es_transpiler.convert_triple(ID_BYPASS_PAYLOAD)
229+
230+
generated_payload = _convert_triple(es_transpiler, ID_BYPASS_PAYLOAD)
209231
check_single_query_payload(ID_BYPASS_PAYLOAD, generated_payload)
210232
must_clauses = generated_payload["query"]["bool"]["filter"]
211233

@@ -225,7 +247,8 @@ def test_bypass_payload(
225247
def test_convert_triple(
226248
q_graph: QueryGraphDict, es_transpiler: ElasticsearchTranspiler
227249
) -> None:
228-
generated_payload = es_transpiler.convert_triple(q_graph)
250+
# generated_payload = es_transpiler.convert_triple(q_graph)
251+
generated_payload = _convert_triple(es_transpiler, q_graph)
229252
check_single_query_payload(q_graph, generated_payload)
230253

231254

@@ -235,7 +258,8 @@ def test_convert_batch_triple(
235258
) -> None:
236259
batch_q_graphs = [q_graph for i in range(10)]
237260

238-
generated_payload_list = es_transpiler.convert_batch_triple(batch_q_graphs)
261+
# generated_payload_list = es_transpiler.convert_batch_triple(batch_q_graphs)
262+
generated_payload_list = _convert_batch_triple(es_transpiler, batch_q_graphs)
239263
for generated_payload in generated_payload_list:
240264
check_single_query_payload(q_graph, generated_payload)
241265

0 commit comments

Comments
 (0)