yangdx commited on
Commit
835046d
·
1 Parent(s): 09ffe28

Add is_truncated to graph query for NetworkX graph db

Browse files
lightrag/base.py CHANGED
@@ -343,7 +343,18 @@ class BaseGraphStorage(StorageNameSpace, ABC):
343
  async def get_knowledge_graph(
344
  self, node_label: str, max_depth: int = 3, max_nodes: int = 1000
345
  ) -> KnowledgeGraph:
346
- """Retrieve a subgraph of the knowledge graph starting from a given node."""
 
 
 
 
 
 
 
 
 
 
 
347
 
348
 
349
  class DocStatus(str, Enum):
 
343
  async def get_knowledge_graph(
344
  self, node_label: str, max_depth: int = 3, max_nodes: int = 1000
345
  ) -> KnowledgeGraph:
346
+ """
347
+ Retrieve a connected subgraph of nodes where the label includes the specified `node_label`.
348
+
349
+ Args:
350
+ node_label: Label of the starting node,* means all nodes
351
+ max_depth: Maximum depth of the subgraph, Defaults to 3
352
+ max_nodes: Maxiumu nodes to return by BFS, Defaults to 1000
353
+
354
+ Returns:
355
+ KnowledgeGraph object containing nodes and edges, with an is_truncated flag
356
+ indicating whether the graph was truncated due to max_nodes limit
357
+ """
358
 
359
 
360
  class DocStatus(str, Enum):
lightrag/kg/neo4j_impl.py CHANGED
@@ -651,17 +651,14 @@ class Neo4JStorage(BaseGraphStorage):
651
  ) -> KnowledgeGraph:
652
  """
653
  Retrieve a connected subgraph of nodes where the label includes the specified `node_label`.
654
- When reducing the number of nodes, the prioritization criteria are as follows:
655
- 1. Hops(path) to the staring node take precedence
656
- 2. Followed by the degree of the nodes
657
 
658
  Args:
659
- node_label: Label of the starting node
660
  max_depth: Maximum depth of the subgraph, Defaults to 3
661
- max_nodes: Maxiumu nodes to return
662
 
663
  Returns:
664
- KnowledgeGraph: Complete connected subgraph for specified node
665
  """
666
  result = KnowledgeGraph()
667
  seen_nodes = set()
 
651
  ) -> KnowledgeGraph:
652
  """
653
  Retrieve a connected subgraph of nodes where the label includes the specified `node_label`.
 
 
 
654
 
655
  Args:
656
+ node_label: Label of the starting node,* means all nodes
657
  max_depth: Maximum depth of the subgraph, Defaults to 3
658
+ max_nodes: Maxiumu nodes to return by BFS, Defaults to 1000
659
 
660
  Returns:
661
+ KnowledgeGraph object containing nodes and edges
662
  """
663
  result = KnowledgeGraph()
664
  seen_nodes = set()
lightrag/kg/networkx_impl.py CHANGED
@@ -270,16 +270,24 @@ class NetworkXStorage(BaseGraphStorage):
270
  max_nodes: Maxiumu nodes to return by BFS, Defaults to 1000
271
 
272
  Returns:
273
- KnowledgeGraph object containing nodes and edges
 
274
  """
275
  graph = await self._get_graph()
276
 
 
 
277
  # Handle special case for "*" label
278
  if node_label == "*":
279
  # Get degrees of all nodes
280
  degrees = dict(graph.degree())
281
  # Sort nodes by degree in descending order and take top max_nodes
282
  sorted_nodes = sorted(degrees.items(), key=lambda x: x[1], reverse=True)
 
 
 
 
 
283
  limited_nodes = [node for node, _ in sorted_nodes[:max_nodes]]
284
  # Create subgraph with the highest degree nodes
285
  subgraph = graph.subgraph(limited_nodes)
@@ -293,23 +301,27 @@ class NetworkXStorage(BaseGraphStorage):
293
  bfs_nodes = []
294
  visited = set()
295
  queue = [node_label]
296
-
297
  # Breadth-first search
298
  while queue and len(bfs_nodes) < max_nodes:
299
  current = queue.pop(0)
300
  if current not in visited:
301
  visited.add(current)
302
  bfs_nodes.append(current)
303
-
304
  # Add neighbor nodes to queue
305
  neighbors = list(graph.neighbors(current))
306
  queue.extend([n for n in neighbors if n not in visited])
307
-
 
 
 
 
 
308
  # Create subgraph with BFS discovered nodes
309
  subgraph = graph.subgraph(bfs_nodes)
310
 
311
  # Add nodes to result
312
- result = KnowledgeGraph()
313
  seen_nodes = set()
314
  seen_edges = set()
315
  for node in subgraph.nodes():
 
270
  max_nodes: Maxiumu nodes to return by BFS, Defaults to 1000
271
 
272
  Returns:
273
+ KnowledgeGraph object containing nodes and edges, with an is_truncated flag
274
+ indicating whether the graph was truncated due to max_nodes limit
275
  """
276
  graph = await self._get_graph()
277
 
278
+ result = KnowledgeGraph()
279
+
280
  # Handle special case for "*" label
281
  if node_label == "*":
282
  # Get degrees of all nodes
283
  degrees = dict(graph.degree())
284
  # Sort nodes by degree in descending order and take top max_nodes
285
  sorted_nodes = sorted(degrees.items(), key=lambda x: x[1], reverse=True)
286
+
287
+ # Check if graph is truncated
288
+ if len(sorted_nodes) > max_nodes:
289
+ result.is_truncated = True
290
+
291
  limited_nodes = [node for node, _ in sorted_nodes[:max_nodes]]
292
  # Create subgraph with the highest degree nodes
293
  subgraph = graph.subgraph(limited_nodes)
 
301
  bfs_nodes = []
302
  visited = set()
303
  queue = [node_label]
304
+
305
  # Breadth-first search
306
  while queue and len(bfs_nodes) < max_nodes:
307
  current = queue.pop(0)
308
  if current not in visited:
309
  visited.add(current)
310
  bfs_nodes.append(current)
311
+
312
  # Add neighbor nodes to queue
313
  neighbors = list(graph.neighbors(current))
314
  queue.extend([n for n in neighbors if n not in visited])
315
+
316
+ # Check if graph is truncated - if we still have nodes in the queue
317
+ # and we've reached max_nodes, then the graph is truncated
318
+ if queue and len(bfs_nodes) >= max_nodes:
319
+ result.is_truncated = True
320
+
321
  # Create subgraph with BFS discovered nodes
322
  subgraph = graph.subgraph(bfs_nodes)
323
 
324
  # Add nodes to result
 
325
  seen_nodes = set()
326
  seen_edges = set()
327
  for node in subgraph.nodes():
lightrag/types.py CHANGED
@@ -26,3 +26,4 @@ class KnowledgeGraphEdge(BaseModel):
26
  class KnowledgeGraph(BaseModel):
27
  nodes: list[KnowledgeGraphNode] = []
28
  edges: list[KnowledgeGraphEdge] = []
 
 
26
  class KnowledgeGraph(BaseModel):
27
  nodes: list[KnowledgeGraphNode] = []
28
  edges: list[KnowledgeGraphEdge] = []
29
+ is_truncated: bool = False