agentrun-mem0ai 0.0.11__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agentrun_mem0/__init__.py +6 -0
- agentrun_mem0/client/__init__.py +0 -0
- agentrun_mem0/client/main.py +1747 -0
- agentrun_mem0/client/project.py +931 -0
- agentrun_mem0/client/utils.py +115 -0
- agentrun_mem0/configs/__init__.py +0 -0
- agentrun_mem0/configs/base.py +90 -0
- agentrun_mem0/configs/embeddings/__init__.py +0 -0
- agentrun_mem0/configs/embeddings/base.py +110 -0
- agentrun_mem0/configs/enums.py +7 -0
- agentrun_mem0/configs/llms/__init__.py +0 -0
- agentrun_mem0/configs/llms/anthropic.py +56 -0
- agentrun_mem0/configs/llms/aws_bedrock.py +192 -0
- agentrun_mem0/configs/llms/azure.py +57 -0
- agentrun_mem0/configs/llms/base.py +62 -0
- agentrun_mem0/configs/llms/deepseek.py +56 -0
- agentrun_mem0/configs/llms/lmstudio.py +59 -0
- agentrun_mem0/configs/llms/ollama.py +56 -0
- agentrun_mem0/configs/llms/openai.py +79 -0
- agentrun_mem0/configs/llms/vllm.py +56 -0
- agentrun_mem0/configs/prompts.py +459 -0
- agentrun_mem0/configs/rerankers/__init__.py +0 -0
- agentrun_mem0/configs/rerankers/base.py +17 -0
- agentrun_mem0/configs/rerankers/cohere.py +15 -0
- agentrun_mem0/configs/rerankers/config.py +12 -0
- agentrun_mem0/configs/rerankers/huggingface.py +17 -0
- agentrun_mem0/configs/rerankers/llm.py +48 -0
- agentrun_mem0/configs/rerankers/sentence_transformer.py +16 -0
- agentrun_mem0/configs/rerankers/zero_entropy.py +28 -0
- agentrun_mem0/configs/vector_stores/__init__.py +0 -0
- agentrun_mem0/configs/vector_stores/alibabacloud_mysql.py +64 -0
- agentrun_mem0/configs/vector_stores/aliyun_tablestore.py +32 -0
- agentrun_mem0/configs/vector_stores/azure_ai_search.py +57 -0
- agentrun_mem0/configs/vector_stores/azure_mysql.py +84 -0
- agentrun_mem0/configs/vector_stores/baidu.py +27 -0
- agentrun_mem0/configs/vector_stores/chroma.py +58 -0
- agentrun_mem0/configs/vector_stores/databricks.py +61 -0
- agentrun_mem0/configs/vector_stores/elasticsearch.py +65 -0
- agentrun_mem0/configs/vector_stores/faiss.py +37 -0
- agentrun_mem0/configs/vector_stores/langchain.py +30 -0
- agentrun_mem0/configs/vector_stores/milvus.py +42 -0
- agentrun_mem0/configs/vector_stores/mongodb.py +25 -0
- agentrun_mem0/configs/vector_stores/neptune.py +27 -0
- agentrun_mem0/configs/vector_stores/opensearch.py +41 -0
- agentrun_mem0/configs/vector_stores/pgvector.py +52 -0
- agentrun_mem0/configs/vector_stores/pinecone.py +55 -0
- agentrun_mem0/configs/vector_stores/qdrant.py +47 -0
- agentrun_mem0/configs/vector_stores/redis.py +24 -0
- agentrun_mem0/configs/vector_stores/s3_vectors.py +28 -0
- agentrun_mem0/configs/vector_stores/supabase.py +44 -0
- agentrun_mem0/configs/vector_stores/upstash_vector.py +34 -0
- agentrun_mem0/configs/vector_stores/valkey.py +15 -0
- agentrun_mem0/configs/vector_stores/vertex_ai_vector_search.py +28 -0
- agentrun_mem0/configs/vector_stores/weaviate.py +41 -0
- agentrun_mem0/embeddings/__init__.py +0 -0
- agentrun_mem0/embeddings/aws_bedrock.py +100 -0
- agentrun_mem0/embeddings/azure_openai.py +55 -0
- agentrun_mem0/embeddings/base.py +31 -0
- agentrun_mem0/embeddings/configs.py +30 -0
- agentrun_mem0/embeddings/gemini.py +39 -0
- agentrun_mem0/embeddings/huggingface.py +44 -0
- agentrun_mem0/embeddings/langchain.py +35 -0
- agentrun_mem0/embeddings/lmstudio.py +29 -0
- agentrun_mem0/embeddings/mock.py +11 -0
- agentrun_mem0/embeddings/ollama.py +53 -0
- agentrun_mem0/embeddings/openai.py +49 -0
- agentrun_mem0/embeddings/together.py +31 -0
- agentrun_mem0/embeddings/vertexai.py +64 -0
- agentrun_mem0/exceptions.py +503 -0
- agentrun_mem0/graphs/__init__.py +0 -0
- agentrun_mem0/graphs/configs.py +105 -0
- agentrun_mem0/graphs/neptune/__init__.py +0 -0
- agentrun_mem0/graphs/neptune/base.py +497 -0
- agentrun_mem0/graphs/neptune/neptunedb.py +511 -0
- agentrun_mem0/graphs/neptune/neptunegraph.py +474 -0
- agentrun_mem0/graphs/tools.py +371 -0
- agentrun_mem0/graphs/utils.py +97 -0
- agentrun_mem0/llms/__init__.py +0 -0
- agentrun_mem0/llms/anthropic.py +87 -0
- agentrun_mem0/llms/aws_bedrock.py +665 -0
- agentrun_mem0/llms/azure_openai.py +141 -0
- agentrun_mem0/llms/azure_openai_structured.py +91 -0
- agentrun_mem0/llms/base.py +131 -0
- agentrun_mem0/llms/configs.py +34 -0
- agentrun_mem0/llms/deepseek.py +107 -0
- agentrun_mem0/llms/gemini.py +201 -0
- agentrun_mem0/llms/groq.py +88 -0
- agentrun_mem0/llms/langchain.py +94 -0
- agentrun_mem0/llms/litellm.py +87 -0
- agentrun_mem0/llms/lmstudio.py +114 -0
- agentrun_mem0/llms/ollama.py +117 -0
- agentrun_mem0/llms/openai.py +147 -0
- agentrun_mem0/llms/openai_structured.py +52 -0
- agentrun_mem0/llms/sarvam.py +89 -0
- agentrun_mem0/llms/together.py +88 -0
- agentrun_mem0/llms/vllm.py +107 -0
- agentrun_mem0/llms/xai.py +52 -0
- agentrun_mem0/memory/__init__.py +0 -0
- agentrun_mem0/memory/base.py +63 -0
- agentrun_mem0/memory/graph_memory.py +698 -0
- agentrun_mem0/memory/kuzu_memory.py +713 -0
- agentrun_mem0/memory/main.py +2229 -0
- agentrun_mem0/memory/memgraph_memory.py +689 -0
- agentrun_mem0/memory/setup.py +56 -0
- agentrun_mem0/memory/storage.py +218 -0
- agentrun_mem0/memory/telemetry.py +90 -0
- agentrun_mem0/memory/utils.py +208 -0
- agentrun_mem0/proxy/__init__.py +0 -0
- agentrun_mem0/proxy/main.py +189 -0
- agentrun_mem0/reranker/__init__.py +9 -0
- agentrun_mem0/reranker/base.py +20 -0
- agentrun_mem0/reranker/cohere_reranker.py +85 -0
- agentrun_mem0/reranker/huggingface_reranker.py +147 -0
- agentrun_mem0/reranker/llm_reranker.py +142 -0
- agentrun_mem0/reranker/sentence_transformer_reranker.py +107 -0
- agentrun_mem0/reranker/zero_entropy_reranker.py +96 -0
- agentrun_mem0/utils/factory.py +283 -0
- agentrun_mem0/utils/gcp_auth.py +167 -0
- agentrun_mem0/vector_stores/__init__.py +0 -0
- agentrun_mem0/vector_stores/alibabacloud_mysql.py +547 -0
- agentrun_mem0/vector_stores/aliyun_tablestore.py +252 -0
- agentrun_mem0/vector_stores/azure_ai_search.py +396 -0
- agentrun_mem0/vector_stores/azure_mysql.py +463 -0
- agentrun_mem0/vector_stores/baidu.py +368 -0
- agentrun_mem0/vector_stores/base.py +58 -0
- agentrun_mem0/vector_stores/chroma.py +332 -0
- agentrun_mem0/vector_stores/configs.py +67 -0
- agentrun_mem0/vector_stores/databricks.py +761 -0
- agentrun_mem0/vector_stores/elasticsearch.py +237 -0
- agentrun_mem0/vector_stores/faiss.py +479 -0
- agentrun_mem0/vector_stores/langchain.py +180 -0
- agentrun_mem0/vector_stores/milvus.py +250 -0
- agentrun_mem0/vector_stores/mongodb.py +310 -0
- agentrun_mem0/vector_stores/neptune_analytics.py +467 -0
- agentrun_mem0/vector_stores/opensearch.py +292 -0
- agentrun_mem0/vector_stores/pgvector.py +404 -0
- agentrun_mem0/vector_stores/pinecone.py +382 -0
- agentrun_mem0/vector_stores/qdrant.py +270 -0
- agentrun_mem0/vector_stores/redis.py +295 -0
- agentrun_mem0/vector_stores/s3_vectors.py +176 -0
- agentrun_mem0/vector_stores/supabase.py +237 -0
- agentrun_mem0/vector_stores/upstash_vector.py +293 -0
- agentrun_mem0/vector_stores/valkey.py +824 -0
- agentrun_mem0/vector_stores/vertex_ai_vector_search.py +635 -0
- agentrun_mem0/vector_stores/weaviate.py +343 -0
- agentrun_mem0ai-0.0.11.data/data/README.md +205 -0
- agentrun_mem0ai-0.0.11.dist-info/METADATA +277 -0
- agentrun_mem0ai-0.0.11.dist-info/RECORD +150 -0
- agentrun_mem0ai-0.0.11.dist-info/WHEEL +4 -0
- agentrun_mem0ai-0.0.11.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import time
|
|
3
|
+
import uuid
|
|
4
|
+
from typing import Dict, List, Optional
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
from langchain_aws import NeptuneAnalyticsGraph
|
|
10
|
+
except ImportError:
|
|
11
|
+
raise ImportError("langchain_aws is not installed. Please install it using pip install langchain_aws")
|
|
12
|
+
|
|
13
|
+
from agentrun_mem0.vector_stores.base import VectorStoreBase
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
class OutputData(BaseModel):
|
|
18
|
+
id: Optional[str] # memory id
|
|
19
|
+
score: Optional[float] # distance
|
|
20
|
+
payload: Optional[Dict] # metadata
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class NeptuneAnalyticsVector(VectorStoreBase):
|
|
24
|
+
"""
|
|
25
|
+
Neptune Analytics vector store implementation for Mem0.
|
|
26
|
+
|
|
27
|
+
Provides vector storage and similarity search capabilities using Amazon Neptune Analytics,
|
|
28
|
+
a serverless graph analytics service that supports vector operations.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
_COLLECTION_PREFIX = "MEM0_VECTOR_"
|
|
32
|
+
_FIELD_N = 'n'
|
|
33
|
+
_FIELD_ID = '~id'
|
|
34
|
+
_FIELD_PROP = '~properties'
|
|
35
|
+
_FIELD_SCORE = 'score'
|
|
36
|
+
_FIELD_LABEL = 'label'
|
|
37
|
+
_TIMEZONE = "UTC"
|
|
38
|
+
|
|
39
|
+
def __init__(
|
|
40
|
+
self,
|
|
41
|
+
endpoint: str,
|
|
42
|
+
collection_name: str,
|
|
43
|
+
):
|
|
44
|
+
"""
|
|
45
|
+
Initialize the Neptune Analytics vector store.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
endpoint (str): Neptune Analytics endpoint in format 'neptune-graph://<graphid>'.
|
|
49
|
+
collection_name (str): Name of the collection to store vectors.
|
|
50
|
+
|
|
51
|
+
Raises:
|
|
52
|
+
ValueError: If endpoint format is invalid.
|
|
53
|
+
ImportError: If langchain_aws is not installed.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
if not endpoint.startswith("neptune-graph://"):
|
|
57
|
+
raise ValueError("Please provide 'endpoint' with the format as 'neptune-graph://<graphid>'.")
|
|
58
|
+
|
|
59
|
+
graph_id = endpoint.replace("neptune-graph://", "")
|
|
60
|
+
self.graph = NeptuneAnalyticsGraph(graph_id)
|
|
61
|
+
self.collection_name = self._COLLECTION_PREFIX + collection_name
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def create_col(self, name, vector_size, distance):
|
|
65
|
+
"""
|
|
66
|
+
Create a collection (no-op for Neptune Analytics).
|
|
67
|
+
|
|
68
|
+
Neptune Analytics supports dynamic indices that are created implicitly
|
|
69
|
+
when vectors are inserted, so this method performs no operation.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
name: Collection name (unused).
|
|
73
|
+
vector_size: Vector dimension (unused).
|
|
74
|
+
distance: Distance metric (unused).
|
|
75
|
+
"""
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def insert(self, vectors: List[list],
|
|
80
|
+
payloads: Optional[List[Dict]] = None,
|
|
81
|
+
ids: Optional[List[str]] = None):
|
|
82
|
+
"""
|
|
83
|
+
Insert vectors into the collection.
|
|
84
|
+
|
|
85
|
+
Creates or updates nodes in Neptune Analytics with vector embeddings and metadata.
|
|
86
|
+
Uses MERGE operation to handle both creation and updates.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
vectors (List[list]): List of embedding vectors to insert.
|
|
90
|
+
payloads (Optional[List[Dict]]): Optional metadata for each vector.
|
|
91
|
+
ids (Optional[List[str]]): Optional IDs for vectors. Generated if not provided.
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
para_list = []
|
|
95
|
+
for index, data_vector in enumerate(vectors):
|
|
96
|
+
if payloads:
|
|
97
|
+
payload = payloads[index]
|
|
98
|
+
payload[self._FIELD_LABEL] = self.collection_name
|
|
99
|
+
payload["updated_at"] = str(int(time.time()))
|
|
100
|
+
else:
|
|
101
|
+
payload = {}
|
|
102
|
+
para_list.append(dict(
|
|
103
|
+
node_id=ids[index] if ids else str(uuid.uuid4()),
|
|
104
|
+
properties=payload,
|
|
105
|
+
embedding=data_vector,
|
|
106
|
+
))
|
|
107
|
+
|
|
108
|
+
para_map_to_insert = {"rows": para_list}
|
|
109
|
+
|
|
110
|
+
query_string = (f"""
|
|
111
|
+
UNWIND $rows AS row
|
|
112
|
+
MERGE (n :{self.collection_name} {{`~id`: row.node_id}})
|
|
113
|
+
ON CREATE SET n = row.properties
|
|
114
|
+
ON MATCH SET n += row.properties
|
|
115
|
+
"""
|
|
116
|
+
)
|
|
117
|
+
self.execute_query(query_string, para_map_to_insert)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
query_string_vector = (f"""
|
|
121
|
+
UNWIND $rows AS row
|
|
122
|
+
MATCH (n
|
|
123
|
+
:{self.collection_name}
|
|
124
|
+
{{`~id`: row.node_id}})
|
|
125
|
+
WITH n, row.embedding AS embedding
|
|
126
|
+
CALL neptune.algo.vectors.upsert(n, embedding)
|
|
127
|
+
YIELD success
|
|
128
|
+
RETURN success
|
|
129
|
+
"""
|
|
130
|
+
)
|
|
131
|
+
result = self.execute_query(query_string_vector, para_map_to_insert)
|
|
132
|
+
self._process_success_message(result, "Vector store - Insert")
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def search(
|
|
136
|
+
self, query: str, vectors: List[float], limit: int = 5, filters: Optional[Dict] = None
|
|
137
|
+
) -> List[OutputData]:
|
|
138
|
+
"""
|
|
139
|
+
Search for similar vectors using embedding similarity.
|
|
140
|
+
|
|
141
|
+
Performs vector similarity search using Neptune Analytics' topKByEmbeddingWithFiltering
|
|
142
|
+
algorithm to find the most similar vectors.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
query (str): Search query text (unused in vector search).
|
|
146
|
+
vectors (List[float]): Query embedding vector.
|
|
147
|
+
limit (int, optional): Maximum number of results to return. Defaults to 5.
|
|
148
|
+
filters (Optional[Dict]): Optional filters to apply to search results.
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
List[OutputData]: List of similar vectors with scores and metadata.
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
if not filters:
|
|
155
|
+
filters = {}
|
|
156
|
+
filters[self._FIELD_LABEL] = self.collection_name
|
|
157
|
+
|
|
158
|
+
filter_clause = self._get_node_filter_clause(filters)
|
|
159
|
+
|
|
160
|
+
query_string = f"""
|
|
161
|
+
CALL neptune.algo.vectors.topKByEmbeddingWithFiltering({{
|
|
162
|
+
topK: {limit},
|
|
163
|
+
embedding: {vectors}
|
|
164
|
+
{filter_clause}
|
|
165
|
+
}}
|
|
166
|
+
)
|
|
167
|
+
YIELD node, score
|
|
168
|
+
RETURN node as n, score
|
|
169
|
+
"""
|
|
170
|
+
query_response = self.execute_query(query_string)
|
|
171
|
+
if len(query_response) > 0:
|
|
172
|
+
return self._parse_query_responses(query_response, with_score=True)
|
|
173
|
+
else :
|
|
174
|
+
return []
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def delete(self, vector_id: str):
|
|
178
|
+
"""
|
|
179
|
+
Delete a vector by its ID.
|
|
180
|
+
|
|
181
|
+
Removes the node and all its relationships from the Neptune Analytics graph.
|
|
182
|
+
|
|
183
|
+
Args:
|
|
184
|
+
vector_id (str): ID of the vector to delete.
|
|
185
|
+
"""
|
|
186
|
+
params = dict(node_id=vector_id)
|
|
187
|
+
query_string = f"""
|
|
188
|
+
MATCH (n :{self.collection_name})
|
|
189
|
+
WHERE id(n) = $node_id
|
|
190
|
+
DETACH DELETE n
|
|
191
|
+
"""
|
|
192
|
+
self.execute_query(query_string, params)
|
|
193
|
+
|
|
194
|
+
def update(
|
|
195
|
+
self,
|
|
196
|
+
vector_id: str,
|
|
197
|
+
vector: Optional[List[float]] = None,
|
|
198
|
+
payload: Optional[Dict] = None,
|
|
199
|
+
):
|
|
200
|
+
"""
|
|
201
|
+
Update a vector's embedding and/or metadata.
|
|
202
|
+
|
|
203
|
+
Updates the node properties and/or vector embedding for an existing vector.
|
|
204
|
+
Can update either the payload, the vector, or both.
|
|
205
|
+
|
|
206
|
+
Args:
|
|
207
|
+
vector_id (str): ID of the vector to update.
|
|
208
|
+
vector (Optional[List[float]]): New embedding vector.
|
|
209
|
+
payload (Optional[Dict]): New metadata to replace existing payload.
|
|
210
|
+
"""
|
|
211
|
+
|
|
212
|
+
if payload:
|
|
213
|
+
# Replace payload
|
|
214
|
+
payload[self._FIELD_LABEL] = self.collection_name
|
|
215
|
+
payload["updated_at"] = str(int(time.time()))
|
|
216
|
+
para_payload = {
|
|
217
|
+
"properties": payload,
|
|
218
|
+
"vector_id": vector_id
|
|
219
|
+
}
|
|
220
|
+
query_string_embedding = f"""
|
|
221
|
+
MATCH (n :{self.collection_name})
|
|
222
|
+
WHERE id(n) = $vector_id
|
|
223
|
+
SET n = $properties
|
|
224
|
+
"""
|
|
225
|
+
self.execute_query(query_string_embedding, para_payload)
|
|
226
|
+
|
|
227
|
+
if vector:
|
|
228
|
+
para_embedding = {
|
|
229
|
+
"embedding": vector,
|
|
230
|
+
"vector_id": vector_id
|
|
231
|
+
}
|
|
232
|
+
query_string_embedding = f"""
|
|
233
|
+
MATCH (n :{self.collection_name})
|
|
234
|
+
WHERE id(n) = $vector_id
|
|
235
|
+
WITH $embedding as embedding, n as n
|
|
236
|
+
CALL neptune.algo.vectors.upsert(n, embedding)
|
|
237
|
+
YIELD success
|
|
238
|
+
RETURN success
|
|
239
|
+
"""
|
|
240
|
+
self.execute_query(query_string_embedding, para_embedding)
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def get(self, vector_id: str):
|
|
245
|
+
"""
|
|
246
|
+
Retrieve a vector by its ID.
|
|
247
|
+
|
|
248
|
+
Fetches the node data including metadata for the specified vector ID.
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
vector_id (str): ID of the vector to retrieve.
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
OutputData: Vector data with metadata, or None if not found.
|
|
255
|
+
"""
|
|
256
|
+
params = dict(node_id=vector_id)
|
|
257
|
+
query_string = f"""
|
|
258
|
+
MATCH (n :{self.collection_name})
|
|
259
|
+
WHERE id(n) = $node_id
|
|
260
|
+
RETURN n
|
|
261
|
+
"""
|
|
262
|
+
|
|
263
|
+
# Composite the query
|
|
264
|
+
result = self.execute_query(query_string, params)
|
|
265
|
+
|
|
266
|
+
if len(result) != 0:
|
|
267
|
+
return self._parse_query_responses(result)[0]
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def list_cols(self):
|
|
271
|
+
"""
|
|
272
|
+
List all collections with the Mem0 prefix.
|
|
273
|
+
|
|
274
|
+
Queries the Neptune Analytics schema to find all node labels that start
|
|
275
|
+
with the Mem0 collection prefix.
|
|
276
|
+
|
|
277
|
+
Returns:
|
|
278
|
+
List[str]: List of collection names.
|
|
279
|
+
"""
|
|
280
|
+
query_string = f"""
|
|
281
|
+
CALL neptune.graph.pg_schema()
|
|
282
|
+
YIELD schema
|
|
283
|
+
RETURN [ label IN schema.nodeLabels WHERE label STARTS WITH '{self.collection_name}'] AS result
|
|
284
|
+
"""
|
|
285
|
+
result = self.execute_query(query_string)
|
|
286
|
+
if len(result) == 1 and "result" in result[0]:
|
|
287
|
+
return result[0]["result"]
|
|
288
|
+
else:
|
|
289
|
+
return []
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def delete_col(self):
|
|
293
|
+
"""
|
|
294
|
+
Delete the entire collection.
|
|
295
|
+
|
|
296
|
+
Removes all nodes with the collection label and their relationships
|
|
297
|
+
from the Neptune Analytics graph.
|
|
298
|
+
"""
|
|
299
|
+
self.execute_query(f"MATCH (n :{self.collection_name}) DETACH DELETE n")
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def col_info(self):
|
|
303
|
+
"""
|
|
304
|
+
Get collection information (no-op for Neptune Analytics).
|
|
305
|
+
|
|
306
|
+
Collections are created dynamically in Neptune Analytics, so no
|
|
307
|
+
collection-specific metadata is available.
|
|
308
|
+
"""
|
|
309
|
+
pass
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def list(self, filters: Optional[Dict] = None, limit: int = 100) -> List[OutputData]:
|
|
313
|
+
"""
|
|
314
|
+
List all vectors in the collection with optional filtering.
|
|
315
|
+
|
|
316
|
+
Retrieves vectors from the collection, optionally filtered by metadata properties.
|
|
317
|
+
|
|
318
|
+
Args:
|
|
319
|
+
filters (Optional[Dict]): Optional filters to apply based on metadata.
|
|
320
|
+
limit (int, optional): Maximum number of vectors to return. Defaults to 100.
|
|
321
|
+
|
|
322
|
+
Returns:
|
|
323
|
+
List[OutputData]: List of vectors with their metadata.
|
|
324
|
+
"""
|
|
325
|
+
where_clause = self._get_where_clause(filters) if filters else ""
|
|
326
|
+
|
|
327
|
+
para = {
|
|
328
|
+
"limit": limit,
|
|
329
|
+
}
|
|
330
|
+
query_string = f"""
|
|
331
|
+
MATCH (n :{self.collection_name})
|
|
332
|
+
{where_clause}
|
|
333
|
+
RETURN n
|
|
334
|
+
LIMIT $limit
|
|
335
|
+
"""
|
|
336
|
+
query_response = self.execute_query(query_string, para)
|
|
337
|
+
|
|
338
|
+
if len(query_response) > 0:
|
|
339
|
+
# Handle if there is no match.
|
|
340
|
+
return [self._parse_query_responses(query_response)]
|
|
341
|
+
return [[]]
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def reset(self):
|
|
345
|
+
"""
|
|
346
|
+
Reset the collection by deleting all vectors.
|
|
347
|
+
|
|
348
|
+
Removes all vectors from the collection, effectively resetting it to empty state.
|
|
349
|
+
"""
|
|
350
|
+
self.delete_col()
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
def _parse_query_responses(self, response: dict, with_score: bool = False):
|
|
354
|
+
"""
|
|
355
|
+
Parse Neptune Analytics query responses into OutputData objects.
|
|
356
|
+
|
|
357
|
+
Args:
|
|
358
|
+
response (dict): Raw query response from Neptune Analytics.
|
|
359
|
+
with_score (bool, optional): Whether to include similarity scores. Defaults to False.
|
|
360
|
+
|
|
361
|
+
Returns:
|
|
362
|
+
List[OutputData]: Parsed response data.
|
|
363
|
+
"""
|
|
364
|
+
result = []
|
|
365
|
+
# Handle if there is no match.
|
|
366
|
+
for item in response:
|
|
367
|
+
id = item[self._FIELD_N][self._FIELD_ID]
|
|
368
|
+
properties = item[self._FIELD_N][self._FIELD_PROP]
|
|
369
|
+
properties.pop("label", None)
|
|
370
|
+
if with_score:
|
|
371
|
+
score = item[self._FIELD_SCORE]
|
|
372
|
+
else:
|
|
373
|
+
score = None
|
|
374
|
+
result.append(OutputData(
|
|
375
|
+
id=id,
|
|
376
|
+
score=score,
|
|
377
|
+
payload=properties,
|
|
378
|
+
))
|
|
379
|
+
return result
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
def execute_query(self, query_string: str, params=None):
|
|
383
|
+
"""
|
|
384
|
+
Execute an openCypher query on Neptune Analytics.
|
|
385
|
+
|
|
386
|
+
This is a wrapper method around the Neptune Analytics graph query execution
|
|
387
|
+
that provides debug logging for query monitoring and troubleshooting.
|
|
388
|
+
|
|
389
|
+
Args:
|
|
390
|
+
query_string (str): The openCypher query string to execute.
|
|
391
|
+
params (dict): Parameters to bind to the query.
|
|
392
|
+
|
|
393
|
+
Returns:
|
|
394
|
+
Query result from Neptune Analytics graph execution.
|
|
395
|
+
"""
|
|
396
|
+
if params is None:
|
|
397
|
+
params = {}
|
|
398
|
+
logger.debug(f"Executing openCypher query:[{query_string}], with parameters:[{params}].")
|
|
399
|
+
return self.graph.query(query_string, params)
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
@staticmethod
|
|
403
|
+
def _get_where_clause(filters: dict):
|
|
404
|
+
"""
|
|
405
|
+
Build WHERE clause for Cypher queries from filters.
|
|
406
|
+
|
|
407
|
+
Args:
|
|
408
|
+
filters (dict): Filter conditions as key-value pairs.
|
|
409
|
+
|
|
410
|
+
Returns:
|
|
411
|
+
str: Formatted WHERE clause for Cypher query.
|
|
412
|
+
"""
|
|
413
|
+
where_clause = ""
|
|
414
|
+
for i, (k, v) in enumerate(filters.items()):
|
|
415
|
+
if i == 0:
|
|
416
|
+
where_clause += f"WHERE n.{k} = '{v}' "
|
|
417
|
+
else:
|
|
418
|
+
where_clause += f"AND n.{k} = '{v}' "
|
|
419
|
+
return where_clause
|
|
420
|
+
|
|
421
|
+
@staticmethod
|
|
422
|
+
def _get_node_filter_clause(filters: dict):
|
|
423
|
+
"""
|
|
424
|
+
Build node filter clause for vector search operations.
|
|
425
|
+
|
|
426
|
+
Creates filter conditions for Neptune Analytics vector search operations
|
|
427
|
+
using the nodeFilter parameter format.
|
|
428
|
+
|
|
429
|
+
Args:
|
|
430
|
+
filters (dict): Filter conditions as key-value pairs.
|
|
431
|
+
|
|
432
|
+
Returns:
|
|
433
|
+
str: Formatted node filter clause for vector search.
|
|
434
|
+
"""
|
|
435
|
+
conditions = []
|
|
436
|
+
for k, v in filters.items():
|
|
437
|
+
conditions.append(f"{{equals:{{property: '{k}', value: '{v}'}}}}")
|
|
438
|
+
|
|
439
|
+
if len(conditions) == 1:
|
|
440
|
+
filter_clause = f", nodeFilter: {conditions[0]}"
|
|
441
|
+
else:
|
|
442
|
+
filter_clause = f"""
|
|
443
|
+
, nodeFilter: {{andAll: [ {", ".join(conditions)} ]}}
|
|
444
|
+
"""
|
|
445
|
+
return filter_clause
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
@staticmethod
|
|
449
|
+
def _process_success_message(response, context):
|
|
450
|
+
"""
|
|
451
|
+
Process and validate success messages from Neptune Analytics operations.
|
|
452
|
+
|
|
453
|
+
Checks the response from vector operations (insert/update) to ensure they
|
|
454
|
+
completed successfully. Logs errors if operations fail.
|
|
455
|
+
|
|
456
|
+
Args:
|
|
457
|
+
response: Response from Neptune Analytics vector operation.
|
|
458
|
+
context (str): Context description for logging (e.g., "Vector store - Insert").
|
|
459
|
+
"""
|
|
460
|
+
for success_message in response:
|
|
461
|
+
if "success" not in success_message:
|
|
462
|
+
logger.error(f"Query execution status is absent on action: [{context}]")
|
|
463
|
+
break
|
|
464
|
+
|
|
465
|
+
if success_message["success"] is not True:
|
|
466
|
+
logger.error(f"Abnormal response status on action: [{context}] with message: [{success_message['success']}] ")
|
|
467
|
+
break
|