Skip to content

Commit de46fe5

Browse files
committed
Reverted _get_hybrid_query
1 parent 5543b8a commit de46fe5

File tree

1 file changed

+38
-44
lines changed

1 file changed

+38
-44
lines changed

src/neo4j_graphrag/neo4j_queries.py

Lines changed: 38 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@
1919
from neo4j_graphrag.filters import get_metadata_filter
2020
from neo4j_graphrag.types import IndexType, SearchType
2121

22+
NODE_VECTOR_INDEX_QUERY = (
23+
"CALL db.index.vector.queryNodes"
24+
"($vector_index_name, $top_k * $effective_search_ratio, $query_vector) "
25+
"YIELD node, score "
26+
"WITH node, score LIMIT $top_k"
27+
)
28+
29+
REL_VECTOR_INDEX_QUERY = (
30+
"CALL db.index.vector.queryRelationships"
31+
"($vector_index_name, $top_k * $effective_search_ratio, $query_vector) "
32+
"YIELD relationship, score "
33+
"WITH relationship, score LIMIT $top_k"
34+
)
35+
2236
VECTOR_EXACT_QUERY = (
2337
"WITH node, "
2438
"vector.similarity.cosine(node.`{embedding_node_property}`, $query_vector) AS score "
@@ -31,6 +45,10 @@
3145
"AND size(node.`{embedding_node_property}`) = toInteger($embedding_dimension)"
3246
)
3347

48+
FULL_TEXT_SEARCH_QUERY = (
49+
"CALL db.index.fulltext.queryNodes($fulltext_index_name, $query_text, {limit: $top_k}) "
50+
"YIELD node, score"
51+
)
3452

3553
UPSERT_NODE_QUERY = (
3654
"UNWIND $rows AS row "
@@ -105,45 +123,19 @@
105123
)
106124

107125

108-
def _get_vector_search_query(index_type: IndexType = IndexType.NODE) -> str:
109-
procedure = "queryNodes" if index_type == IndexType.NODE else "queryRelationships"
110-
return (
111-
f"CALL db.index.vector.{procedure}"
112-
"($vector_index_name, $top_k * $effective_search_ratio, $query_vector) "
113-
f"YIELD {index_type.value}, score "
114-
f"WITH {index_type.value}, score LIMIT $top_k"
115-
)
116-
117-
118-
def _get_full_text_search_query(index_type: IndexType = IndexType.NODE) -> str:
119-
procedure = "queryNodes" if index_type == IndexType.NODE else "queryRelationships"
120-
return (
121-
f"CALL db.index.fulltext.{procedure}"
122-
"($fulltext_index_name, $query_text, {limit: $top_k}) "
123-
f"YIELD {index_type.value}, score"
124-
)
125-
126-
127-
def _get_hybrid_query(
128-
neo4j_version_is_5_23_or_above: bool, index_type: IndexType = IndexType.NODE
129-
) -> str:
126+
def _get_hybrid_query(neo4j_version_is_5_23_or_above: bool) -> str:
130127
call_prefix = "CALL () { " if neo4j_version_is_5_23_or_above else "CALL { "
131-
vector_search_query = _get_vector_search_query(index_type=index_type)
132-
full_text_search_query = _get_full_text_search_query(index_type=index_type)
133128
query_body = (
134-
f"{vector_search_query} "
135-
f"WITH collect({{{index_type.value}:{index_type.value}, score:score}}) AS {index_type.value}s, "
136-
"max(score) AS vector_index_max_score "
137-
f"UNWIND {index_type.value}s AS n "
138-
f"RETURN n.{index_type.value} AS {index_type.value}, (n.score / vector_index_max_score) AS score "
129+
f"{NODE_VECTOR_INDEX_QUERY} "
130+
"WITH collect({node:node, score:score}) AS nodes, max(score) AS vector_index_max_score "
131+
"UNWIND nodes AS n "
132+
"RETURN n.node AS node, (n.score / vector_index_max_score) AS score "
139133
"UNION "
140-
f"{full_text_search_query} "
141-
f"WITH collect({{{index_type.value}:{index_type.value}, score:score}}) AS {index_type.value}s, "
142-
"max(score) AS ft_index_max_score "
143-
f"UNWIND {index_type.value}s AS n "
144-
f"RETURN n.{index_type.value} AS {index_type.value}, (n.score / ft_index_max_score) AS score "
145-
"} "
146-
f"WITH {index_type.value}, max(score) AS score ORDER BY score DESC LIMIT $top_k"
134+
f"{FULL_TEXT_SEARCH_QUERY} "
135+
"WITH collect({node:node, score:score}) AS nodes, max(score) AS ft_index_max_score "
136+
"UNWIND nodes AS n "
137+
"RETURN n.node AS node, (n.score / ft_index_max_score) AS score } "
138+
"WITH node, max(score) AS score ORDER BY score DESC LIMIT $top_k"
147139
)
148140
return call_prefix + query_body
149141

@@ -219,7 +211,7 @@ def get_search_query(
219211
if index_type == IndexType.NODE:
220212
if search_type == SearchType.HYBRID:
221213
if filters:
222-
raise Exception("Filters are not supported with Hybrid Search")
214+
raise Exception("Filters are not supported with hybrid search")
223215
query = _get_hybrid_query(neo4j_version_is_5_23_or_above)
224216
params: dict[str, Any] = {}
225217
elif search_type == SearchType.VECTOR:
@@ -240,24 +232,26 @@ def get_search_query(
240232
"Vector Search with filters requires: node_label, embedding_node_property, embedding_dimension"
241233
)
242234
else:
243-
query, params = _get_vector_search_query(index_type=index_type), {}
235+
query, params = NODE_VECTOR_INDEX_QUERY, {}
244236
else:
245237
raise ValueError(f"Search type is not supported: {search_type}")
246238
fallback_return = (
247239
f"RETURN node {{ .*, `{embedding_node_property}`: null }} AS node, "
248240
"labels(node) AS nodeLabels, elementId(node) AS elementId, score"
249241
)
250242
elif index_type == IndexType.RELATIONSHIP:
243+
if filters:
244+
raise Exception("Filters are not supported for relationship indexes")
251245
if search_type == SearchType.HYBRID:
252-
raise Exception("Hybrid search is not support for relationship indexes")
246+
raise Exception("Hybrid search is not supported for relationship indexes")
253247
elif search_type == SearchType.VECTOR:
254-
query, params = _get_vector_search_query(index_type=index_type), {}
248+
query, params = REL_VECTOR_INDEX_QUERY, {}
249+
fallback_return = (
250+
f"RETURN relationship {{ .*, `{embedding_node_property}`: null }} AS relationship, "
251+
"elementId(relationship) AS elementId, score"
252+
)
255253
else:
256254
raise ValueError(f"Search type is not supported: {search_type}")
257-
fallback_return = (
258-
f"RETURN relationship {{ .*, `{embedding_node_property}`: null }} AS relationship, "
259-
"elementId(relationship) AS elementId, score"
260-
)
261255
else:
262256
raise ValueError(f"Index type is not supported: {index_type}")
263257

0 commit comments

Comments
 (0)