Ken Wiltshire commited on
Commit
836c74a
·
1 Parent(s): 6448286

edge degree next almost done

Browse files
.DS_Store ADDED
Binary file (8.2 kB). View file
 
lightrag/kg/neo4j.py CHANGED
@@ -5,6 +5,8 @@ from dataclasses import dataclass
5
  from typing import Any, Union, cast
6
  import numpy as np
7
  from nano_vectordb import NanoVectorDB
 
 
8
 
9
 
10
 
@@ -26,14 +28,12 @@ PASSWORD = "your_password"
26
  @dataclass
27
  class GraphStorage(BaseGraphStorage):
28
  @staticmethod
29
- # def load_nx_graph(file_name) -> nx.Graph:
30
- # if os.path.exists(file_name):
31
- # return nx.read_graphml(file_name)
32
- # return None
33
 
34
  def __post_init__(self):
35
  # self._graph = preloaded_graph or nx.Graph()
36
- self._driver = GraphDatabase.driver(URI, auth=(USERNAME, PASSWORD))
37
  self._node_embed_algorithms = {
38
  "node2vec": self._node2vec_embed,
39
  }
@@ -41,79 +41,111 @@ class GraphStorage(BaseGraphStorage):
41
  async def index_done_callback(self):
42
  print ("KG successfully indexed.")
43
  async def has_node(self, node_id: str) -> bool:
44
- entity_name_label = node_id
45
- with self._driver.session() as session:
46
- return session.read_transaction(self._check_node_exists, entity_name_label)
47
 
48
- @staticmethod
49
  def _check_node_exists(tx, label):
50
- query = f"MATCH (n:{label}) RETURN count(n) > 0 AS node_exists"
51
  result = tx.run(query)
52
- return result.single()["node_exists"]
 
 
 
 
 
53
 
54
- async def has_edge(self, source_node_id: str, target_node_id: str) -> bool:
55
- entity_name_label_source = source_node_id
56
- entity_name_label_target = target_node_id
57
- #hard code relaitionship type
58
  with self._driver.session() as session:
59
- result = session.read_transaction(self._check_edge_existence, entity_name_label_source, entity_name_label_target)
60
- return result
 
 
 
 
 
61
 
62
- @staticmethod
63
  def _check_edge_existence(tx, label1, label2):
64
  query = (
65
- f"MATCH (a:{label1})-[r]-(b:{label2}) "
66
  "RETURN COUNT(r) > 0 AS edgeExists"
67
  )
68
  result = tx.run(query)
69
- return result.single()["edgeExists"]
 
 
 
 
 
 
 
 
70
  def close(self):
71
- self._driver.close()
 
 
 
 
72
 
73
 
74
 
75
  async def get_node(self, node_id: str) -> Union[dict, None]:
76
- entity_name_label = node_id
77
  with self._driver.session() as session:
78
- result = session.run("MATCH (n:{entity_name_label}) RETURN n".format(entity_name_label=entity_name_label))
 
79
  for record in result:
80
- return record["n"]
 
 
 
 
81
 
82
 
83
 
84
  async def node_degree(self, node_id: str) -> int:
85
- entity_name_label = node_id
86
- with self._driver.session() as session:
87
- degree = self._find_node_degree(session, entity_name_label)
88
- return degree
89
 
90
- @staticmethod
91
  def _find_node_degree(session, label):
92
  with session.begin_transaction() as tx:
93
- result = tx.run("MATCH (n:`{label}`) RETURN n, size((n)--()) AS degree".format(label=label))
 
 
 
 
 
94
  record = result.single()
95
- if record:
96
- return record["degree"]
 
 
 
 
97
  else:
98
  return None
 
 
 
 
99
 
100
 
101
  # degree = session.read_transaction(get_edge_degree, 1, 2)
102
  async def edge_degree(self, src_id: str, tgt_id: str) -> int:
103
- entity_name__label_source = src_id
104
- entity_name_label_target = tgt_id
105
  with self._driver.session() as session:
106
- result = session.run(
107
- """MATCH (n1:{node_label1})-[r]-(n2:{node_label2})
108
- RETURN count(r) AS degree"""
109
- .format(entity_name__label_source=entity_name__label_source, entity_name_label_target=entity_name_label_target)
110
- )
111
- record = result.single()
 
 
 
112
  return record["degree"]
113
 
114
  async def get_edge(self, source_node_id: str, target_node_id: str) -> Union[dict, None]:
115
- entity_name__label_source = source_node_id
116
- entity_name_label_target = target_node_id
117
  """
118
  Find all edges between nodes of two given labels
119
 
@@ -126,17 +158,109 @@ class GraphStorage(BaseGraphStorage):
126
  """
127
  with self._driver.session() as session:
128
  query = f"""
129
- MATCH (source:{entity_name__label_source})-[r]-(target:{entity_name_label_target})
130
  RETURN r
131
  """
132
 
133
  result = session.run(query)
 
 
 
 
 
 
134
  return [record["r"] for record in result]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
 
 
 
136
 
137
- #upsert_node
 
 
 
 
138
  async def upsert_node(self, node_id: str, node_data: dict[str, str]):
139
- label = node_id
140
  properties = node_data
141
  """
142
  Upsert a node with the given label and properties within a transaction.
@@ -152,21 +276,9 @@ class GraphStorage(BaseGraphStorage):
152
  Returns:
153
  Dictionary containing the node's properties after upsert, or None if operation fails
154
  """
155
- with self._driver.session() as session:
156
- # Execute the upsert within a transaction
157
- result = session.execute_write(
158
- self._do_upsert,
159
- label,
160
- properties
161
- )
162
- return result
163
-
164
 
165
- @staticmethod
166
- def _do_upsert(tx: Transaction, label: str, properties: Dict[str, Any]):
167
- """
168
- Static method to perform the actual upsert operation within a transaction
169
-
170
  Args:
171
  tx: Neo4j transaction object
172
  label: The node label to search for and apply
@@ -175,44 +287,39 @@ class GraphStorage(BaseGraphStorage):
175
  Returns:
176
  Dictionary containing the node's properties after upsert, or None if operation fails
177
  """
178
- # Create the dynamic property string for SET clause
179
- property_string = ", ".join([
180
- f"n.{key} = ${key}"
181
- for key in properties.keys()
182
- ])
183
-
184
- # Cypher query that either matches existing node or creates new one
185
  query = f"""
186
- MATCH (n:{label})
187
- WITH n LIMIT 1
188
- CALL {{
189
- WITH n
190
- WHERE n IS NOT NULL
191
- SET {property_string}
192
- RETURN n
193
- UNION
194
- WITH n
195
- WHERE n IS NULL
196
- CREATE (n:{label})
197
- SET {property_string}
198
- RETURN n
199
- }}
200
  RETURN n
201
  """
202
-
203
- # Execute the query with properties as parameters
204
- result = tx.run(query, properties)
205
- record = result.single()
206
-
207
- if record:
208
- return dict(record["n"])
209
- return None
210
-
211
-
 
 
 
 
 
 
 
 
 
 
 
 
212
 
213
  async def upsert_edge(self, source_node_id: str, target_node_id: str, edge_data: dict[str, str]) -> None:
214
- source_node_label = source_node_id
215
- target_node_label = target_node_id
 
216
  """
217
  Upsert an edge and its properties between two nodes identified by their labels.
218
 
@@ -221,16 +328,10 @@ class GraphStorage(BaseGraphStorage):
221
  target_node_label (str): Label of the target node (used as identifier)
222
  edge_properties (dict): Dictionary of properties to set on the edge
223
  """
224
- with self._driver.session() as session:
225
- session.execute_write(
226
- self._do_upsert_edge,
227
- source_node_label,
228
- target_node_label,
229
- edge_data
230
- )
231
 
232
- @staticmethod
233
- def _do_upsert_edge(tx, source_node_label: str, target_node_label: str, edge_properties: Dict[str, Any]) -> None:
234
  """
235
  Static method to perform the edge upsert within a transaction.
236
 
@@ -240,43 +341,58 @@ class GraphStorage(BaseGraphStorage):
240
  3. Set all properties on the relationship, updating existing ones and adding new ones
241
  """
242
  # Convert edge properties to Cypher parameter string
243
- props_string = ", ".join(f"r.{key} = ${key}" for key in edge_properties.keys())
244
-
245
- query = """
246
- MATCH (source)
247
- WHERE source.label = $source_node_label
248
- MATCH (target)
249
- WHERE target.label = $target_node_label
250
  MERGE (source)-[r:DIRECTED]->(target)
251
- SET {}
252
- """.format(props_string)
253
-
254
- # Prepare parameters dictionary
255
- params = {
256
- "source_node_label": source_node_label,
257
- "target_node_label": target_node_label,
258
- **edge_properties
259
- }
260
-
261
- # Execute the query
262
- tx.run(query, params)
263
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
 
265
  async def _node2vec_embed(self):
266
  # async def _node2vec_embed(self):
267
  with self._driver.session() as session:
268
  #Define the Cypher query
269
  options = self.global_config["node2vec_params"]
270
- query = f"""CALL gds.node2vec.stream('myGraph', {options}) # **options
271
- YIELD nodeId, embedding
272
- RETURN nodeId, embedding"""
 
 
 
 
 
 
 
273
  # Run the query and process the results
274
  results = session.run(query)
 
 
275
  for record in results:
276
- node_id = record["nodeId"]
277
- embedding = record["embedding"]
278
- print(f"Node ID: {node_id}, Embedding: {embedding}")
279
- #need to return two lists here.
280
-
281
-
 
282
 
 
5
  from typing import Any, Union, cast
6
  import numpy as np
7
  from nano_vectordb import NanoVectorDB
8
+ import inspect
9
+
10
 
11
 
12
 
 
28
  @dataclass
29
  class GraphStorage(BaseGraphStorage):
30
  @staticmethod
31
+ def load_nx_graph(file_name):
32
+ print ("no preloading of graph with neo4j in production")
 
 
33
 
34
  def __post_init__(self):
35
  # self._graph = preloaded_graph or nx.Graph()
36
+ self._driver = GraphDatabase.driver("neo4j+s://91fbae6c.databases.neo4j.io", auth=("neo4j", "KWKPXfXcClDbUlmDdGgIQhU5mL1N4E_2CJp2BDFbEbw"))
37
  self._node_embed_algorithms = {
38
  "node2vec": self._node2vec_embed,
39
  }
 
41
  async def index_done_callback(self):
42
  print ("KG successfully indexed.")
43
  async def has_node(self, node_id: str) -> bool:
44
+ entity_name_label = node_id.strip('\"')
 
 
45
 
 
46
  def _check_node_exists(tx, label):
47
+ query = f"MATCH (n:`{label}`) RETURN count(n) > 0 AS node_exists"
48
  result = tx.run(query)
49
+ single_result = result.single()
50
+ logger.info(
51
+ f'{inspect.currentframe().f_code.co_name}:query:{query}:result:{single_result["node_exists"]}'
52
+ )
53
+
54
+ return single_result["node_exists"]
55
 
 
 
 
 
56
  with self._driver.session() as session:
57
+ return session.read_transaction(_check_node_exists, entity_name_label)
58
+
59
+
60
+ async def has_edge(self, source_node_id: str, target_node_id: str) -> bool:
61
+ entity_name_label_source = source_node_id.strip('\"')
62
+ entity_name_label_target = target_node_id.strip('\"')
63
+
64
 
 
65
  def _check_edge_existence(tx, label1, label2):
66
  query = (
67
+ f"MATCH (a:`{label1}`)-[r]-(b:`{label2}`) "
68
  "RETURN COUNT(r) > 0 AS edgeExists"
69
  )
70
  result = tx.run(query)
71
+ single_result = result.single()
72
+ # if result.single() == None:
73
+ # print (f"this should not happen: ---- {label1}/{label2} {query}")
74
+
75
+ logger.info(
76
+ f'{inspect.currentframe().f_code.co_name}:query:{query}:result:{single_result["edgeExists"]}'
77
+ )
78
+
79
+ return single_result["edgeExists"]
80
  def close(self):
81
+ self._driver.close()
82
+ #hard code relaitionship type
83
+ with self._driver.session() as session:
84
+ result = session.read_transaction(_check_edge_existence, entity_name_label_source, entity_name_label_target)
85
+ return result
86
 
87
 
88
 
89
  async def get_node(self, node_id: str) -> Union[dict, None]:
90
+ entity_name_label = node_id.strip('\"')
91
  with self._driver.session() as session:
92
+ query = "MATCH (n:`{entity_name_label}`) RETURN n".format(entity_name_label=entity_name_label)
93
+ result = session.run(query)
94
  for record in result:
95
+ result = record["n"]
96
+ logger.info(
97
+ f'{inspect.currentframe().f_code.co_name}:query:{query}:result:{result}'
98
+ )
99
+ return result
100
 
101
 
102
 
103
  async def node_degree(self, node_id: str) -> int:
104
+ entity_name_label = node_id.strip('\"')
105
+
 
 
106
 
 
107
  def _find_node_degree(session, label):
108
  with session.begin_transaction() as tx:
109
+ # query = "MATCH (n:`{label}`) RETURN n, size((n)--()) AS degree".format(label=label)
110
+ query = f"""
111
+ MATCH (n:`{label}`)
112
+ RETURN COUNT{{ (n)--() }} AS totalEdgeCount
113
+ """
114
+ result = tx.run(query)
115
  record = result.single()
116
+ if record:
117
+ edge_count = record["totalEdgeCount"]
118
+ logger.info(
119
+ f'{inspect.currentframe().f_code.co_name}:query:{query}:result:{edge_count}'
120
+ )
121
+ return edge_count
122
  else:
123
  return None
124
+
125
+ with self._driver.session() as session:
126
+ degree = _find_node_degree(session, entity_name_label)
127
+ return degree
128
 
129
 
130
  # degree = session.read_transaction(get_edge_degree, 1, 2)
131
  async def edge_degree(self, src_id: str, tgt_id: str) -> int:
132
+ entity_name__label_source = src_id.strip('\"')
133
+ entity_name_label_target = tgt_id.strip('\"')
134
  with self._driver.session() as session:
135
+ query = """MATCH (n1:`{node_label1}`)-[r]-(n2:`{node_label2}`)
136
+ RETURN count(r) AS degree""".format(entity_name__label_source=entity_name__label_source,
137
+ entity_name_label_target=entity_name_label_target)
138
+
139
+ result = session.run(query)
140
+ record = result.single()
141
+ logger.info(
142
+ f'{inspect.currentframe().f_code.co_name}:query:{query}:result:{record["degree"]}'
143
+ )
144
  return record["degree"]
145
 
146
  async def get_edge(self, source_node_id: str, target_node_id: str) -> Union[dict, None]:
147
+ entity_name__label_source = source_node_id.strip('\"')
148
+ entity_name_label_target = target_node_id.strip('\"')
149
  """
150
  Find all edges between nodes of two given labels
151
 
 
158
  """
159
  with self._driver.session() as session:
160
  query = f"""
161
+ MATCH (source:`{entity_name__label_source}`)-[r]-(target:`{entity_name_label_target}`)
162
  RETURN r
163
  """
164
 
165
  result = session.run(query)
166
+ for logrecord in result:
167
+ logger.info(
168
+ f'{inspect.currentframe().f_code.co_name}:query:{query}:result:{logrecord["r"]}'
169
+ )
170
+
171
+
172
  return [record["r"] for record in result]
173
+
174
+
175
+
176
+ async def get_node_edges(self, source_node_id: str):
177
+ if self._graph.has_node(source_node_id):
178
+ return list(self._graph.edges(source_node_id))
179
+ return None
180
+
181
+ async def get_node_edges(self, source_node_id: str):
182
+ node_label = source_node_id.strip('\"')
183
+
184
+ """
185
+ Retrieves all edges (relationships) for a particular node identified by its label and ID.
186
+
187
+ :param uri: Neo4j database URI
188
+ :param username: Neo4j username
189
+ :param password: Neo4j password
190
+ :param node_label: Label of the node
191
+ :param node_id: ID property of the node
192
+ :return: List of dictionaries containing edge information
193
+ """
194
+
195
+ def fetch_edges(tx, label):
196
+ query = f"""MATCH (n:`{label}`)
197
+ OPTIONAL MATCH (n)-[r]-(connected)
198
+ RETURN n, r, connected"""
199
+
200
+ results = tx.run(query)
201
+
202
+ edges = []
203
+ for record in results:
204
+ source_node = record['n']
205
+ connected_node = record['connected']
206
+
207
+ source_label = list(source_node.labels)[0] if source_node.labels else None
208
+ target_label = list(connected_node.labels)[0] if connected_node and connected_node.labels else None
209
+
210
+ if source_label and target_label:
211
+ print (f"appending: {[source_label, target_label]}")
212
+ edges.append([source_label, target_label])
213
+
214
+ return edges
215
+
216
+ with self._driver.session() as session:
217
+ edges = session.read_transaction(fetch_edges,node_label)
218
+ return edges
219
+
220
+
221
+ # try:
222
+ # with self._driver.session() as session:
223
+ # if self.has_node(node_label):
224
+ # edges = session.read_transaction(fetch_edges,node_label)
225
+ # return list(edges)
226
+ # return edges
227
+ # finally:
228
+ # print ("consider closign driver here")
229
+ # # driver.close()
230
+
231
+ from typing import List, Tuple
232
+ async def get_node_connections(driver: GraphDatabase.driver, label: str) -> List[Tuple[str, str]]:
233
+ def run_query(tx):
234
+ query = f"""
235
+ MATCH (n:`{label}`)
236
+ OPTIONAL MATCH (n)-[r]-(connected)
237
+ RETURN n, r, connected
238
+ """
239
+ results = tx.run(query)
240
+
241
+ connections = []
242
+ for record in results:
243
+ source_node = record['n']
244
+ connected_node = record['connected']
245
+
246
+ source_label = list(source_node.labels)[0] if source_node.labels else None
247
+ target_label = list(connected_node.labels)[0] if connected_node and connected_node.labels else None
248
+
249
+ if source_label and target_label:
250
+ connections.append((source_label, target_label))
251
+
252
+ return connections
253
 
254
+ with driver.session() as session:
255
+ return session.read_transaction(run_query)
256
 
257
+
258
+
259
+
260
+
261
+ #upsert_node
262
  async def upsert_node(self, node_id: str, node_data: dict[str, str]):
263
+ label = node_id.strip('\"')
264
  properties = node_data
265
  """
266
  Upsert a node with the given label and properties within a transaction.
 
276
  Returns:
277
  Dictionary containing the node's properties after upsert, or None if operation fails
278
  """
279
+ def _do_upsert(tx, label: str, properties: dict[str, Any]):
 
 
 
 
 
 
 
 
280
 
281
+ """
 
 
 
 
282
  Args:
283
  tx: Neo4j transaction object
284
  label: The node label to search for and apply
 
287
  Returns:
288
  Dictionary containing the node's properties after upsert, or None if operation fails
289
  """
290
+
 
 
 
 
 
 
291
  query = f"""
292
+ MERGE (n:`{label}`)
293
+ SET n += $properties
 
 
 
 
 
 
 
 
 
 
 
 
294
  RETURN n
295
  """
296
+ # Execute the query with properties as parameters
297
+ # with session.begin_transaction() as tx:
298
+ result = tx.run(query, properties=properties)
299
+ record = result.single()
300
+ if record:
301
+ logger.info(
302
+ f'{inspect.currentframe().f_code.co_name}:query:{query}:result:{dict(record["n"])}'
303
+ )
304
+ return dict(record["n"])
305
+ return None
306
+
307
+
308
+ with self._driver.session() as session:
309
+ with session.begin_transaction() as tx:
310
+ try:
311
+ result = _do_upsert(tx,label,properties)
312
+ tx.commit()
313
+ return result
314
+ except Exception as e:
315
+ raise # roll back
316
+
317
+
318
 
319
  async def upsert_edge(self, source_node_id: str, target_node_id: str, edge_data: dict[str, str]) -> None:
320
+ source_node_label = source_node_id.strip('\"')
321
+ target_node_label = target_node_id.strip('\"')
322
+ edge_properties = edge_data
323
  """
324
  Upsert an edge and its properties between two nodes identified by their labels.
325
 
 
328
  target_node_label (str): Label of the target node (used as identifier)
329
  edge_properties (dict): Dictionary of properties to set on the edge
330
  """
331
+
 
 
 
 
 
 
332
 
333
+
334
+ def _do_upsert_edge(tx, source_node_label: str, target_node_label: str, edge_properties: dict[str, Any]) -> None:
335
  """
336
  Static method to perform the edge upsert within a transaction.
337
 
 
341
  3. Set all properties on the relationship, updating existing ones and adding new ones
342
  """
343
  # Convert edge properties to Cypher parameter string
344
+ # props_string = ", ".join(f"r.{key} = ${key}" for key in edge_properties.keys())
345
+
346
+ # """.format(props_string)
347
+ query = f"""
348
+ MATCH (source:`{source_node_label}`)
349
+ WITH source
350
+ MATCH (target:`{target_node_label}`)
351
  MERGE (source)-[r:DIRECTED]->(target)
352
+ SET r += $properties
353
+ RETURN r
354
+ """
 
 
 
 
 
 
 
 
 
355
 
356
+ result = tx.run(query, properties=edge_properties)
357
+ logger.info(
358
+ f'{inspect.currentframe().f_code.co_name}:query:{query}:result:{None}'
359
+ )
360
+ return result.single()
361
+
362
+ with self._driver.session() as session:
363
+ session.execute_write(
364
+ _do_upsert_edge,
365
+ source_node_label,
366
+ target_node_label,
367
+ edge_properties
368
+ )
369
+ # return result
370
 
371
  async def _node2vec_embed(self):
372
  # async def _node2vec_embed(self):
373
  with self._driver.session() as session:
374
  #Define the Cypher query
375
  options = self.global_config["node2vec_params"]
376
+ logger.info(f"building embeddings with options {options}")
377
+ query = f"""CALL gds.node2vec.write('91fbae6c', {
378
+ options
379
+ })
380
+ YIELD nodeId, labels, embedding
381
+ RETURN
382
+ nodeId AS id,
383
+ labels[0] AS distinctLabel,
384
+ embedding AS nodeToVecEmbedding
385
+ """
386
  # Run the query and process the results
387
  results = session.run(query)
388
+ embeddings = []
389
+ node_labels = []
390
  for record in results:
391
+ node_id = record["id"]
392
+ embedding = record["nodeToVecEmbedding"]
393
+ label = record["distinctLabel"]
394
+ print(f"Node id/label: {label}/{node_id}, Embedding: {embedding}")
395
+ embeddings.append(embedding)
396
+ node_labels.append(label)
397
+ return embeddings, node_labels
398
 
lightrag/lightrag.py CHANGED
@@ -103,7 +103,7 @@ class LightRAG:
103
  # module = importlib.import_module('kg.neo4j')
104
  # Neo4JStorage = getattr(module, 'GraphStorage')
105
 
106
- if True==False:
107
  graph_storage_cls: Type[BaseGraphStorage] = Neo4JStorage
108
  else:
109
  graph_storage_cls: Type[BaseGraphStorage] = NetworkXStorage
 
103
  # module = importlib.import_module('kg.neo4j')
104
  # Neo4JStorage = getattr(module, 'GraphStorage')
105
 
106
+ if True==True:
107
  graph_storage_cls: Type[BaseGraphStorage] = Neo4JStorage
108
  else:
109
  graph_storage_cls: Type[BaseGraphStorage] = NetworkXStorage
lightrag/llm.py CHANGED
@@ -73,7 +73,7 @@ async def openai_complete_if_cache(
73
  @retry(
74
  stop=stop_after_attempt(3),
75
  #kw_
76
- wait=wait_exponential(multiplier=1, min=4, max=60),
77
  # wait=wait_exponential(multiplier=1, min=4, max=10),
78
  retry=retry_if_exception_type((RateLimitError, APIConnectionError, Timeout)),
79
  )
 
73
  @retry(
74
  stop=stop_after_attempt(3),
75
  #kw_
76
+ wait=wait_exponential(multiplier=1, min=10, max=60),
77
  # wait=wait_exponential(multiplier=1, min=4, max=10),
78
  retry=retry_if_exception_type((RateLimitError, APIConnectionError, Timeout)),
79
  )
neo4jWorkDir/kv_store_full_docs.json ADDED
The diff for this file is too large to render. See raw diff
 
neo4jWorkDir/kv_store_llm_response_cache.json ADDED
The diff for this file is too large to render. See raw diff
 
neo4jWorkDir/kv_store_text_chunks.json ADDED
The diff for this file is too large to render. See raw diff
 
neo4jWorkDir/lightrag.log ADDED
The diff for this file is too large to render. See raw diff
 
neo4jWorkDir/vdb_chunks.json ADDED
The diff for this file is too large to render. See raw diff
 
neo4jWorkDir/vdb_entities.json ADDED
The diff for this file is too large to render. See raw diff
 
neo4jWorkDir/vdb_relationships.json ADDED
The diff for this file is too large to render. See raw diff
 
testkg.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from lightrag import LightRAG, QueryParam
3
+ from lightrag.llm import gpt_4o_mini_complete, gpt_4o_complete
4
+
5
+ #########
6
+ # Uncomment the below two lines if running in a jupyter notebook to handle the async nature of rag.insert()
7
+ # import nest_asyncio
8
+ # nest_asyncio.apply()
9
+ #########
10
+
11
+ WORKING_DIR = "./neo4jWorkDir"
12
+
13
+
14
+ if not os.path.exists(WORKING_DIR):
15
+ os.mkdir(WORKING_DIR)
16
+
17
+ rag = LightRAG(
18
+ working_dir=WORKING_DIR,
19
+ llm_model_func=gpt_4o_mini_complete # Use gpt_4o_mini_complete LLM model
20
+ # llm_model_func=gpt_4o_complete # Optionally, use a stronger model
21
+ )
22
+
23
+ with open("./book.txt") as f:
24
+ rag.insert(f.read())
25
+
26
+ # Perform naive search
27
+ print(rag.query("What are the top themes in this story?", param=QueryParam(mode="naive")))
28
+
29
+ # Perform local search
30
+ print(rag.query("What are the top themes in this story?", param=QueryParam(mode="local")))
31
+
32
+ # Perform global search
33
+ print(rag.query("What are the top themes in this story?", param=QueryParam(mode="global")))
34
+
35
+ # Perform hybrid search
36
+ print(rag.query("What are the top themes in this story?", param=QueryParam(mode="hybrid")))