yangdx commited on
Commit
fbf138f
·
1 Parent(s): 0244726

Simplified graph retrival by removing inclusive and min_degree parameters

Browse files
lightrag/api/routers/graph_routes.py CHANGED
@@ -41,7 +41,7 @@ def create_graph_routes(rag, api_key: Optional[str] = None):
41
  label (str): Label to get knowledge graph for
42
  max_depth (int, optional): Maximum depth of graph. Defaults to 3.
43
  inclusive_search (bool, optional): If True, search for nodes that include the label. Defaults to False.
44
- min_degree (int, optional): Minimum degree of nodes. Defaults to 0.
45
 
46
  Returns:
47
  Dict[str, List[str]]: Knowledge graph for label
@@ -49,8 +49,6 @@ def create_graph_routes(rag, api_key: Optional[str] = None):
49
  return await rag.get_knowledge_graph(
50
  node_label=label,
51
  max_depth=max_depth,
52
- inclusive=inclusive,
53
- min_degree=min_degree,
54
  )
55
 
56
  return router
 
41
  label (str): Label to get knowledge graph for
42
  max_depth (int, optional): Maximum depth of graph. Defaults to 3.
43
  inclusive_search (bool, optional): If True, search for nodes that include the label. Defaults to False.
44
+ min_degree (int, optional): Minimum degree of nodes. Defaults to 0. (Deprecated, always 0)
45
 
46
  Returns:
47
  Dict[str, List[str]]: Knowledge graph for label
 
49
  return await rag.get_knowledge_graph(
50
  node_label=label,
51
  max_depth=max_depth,
 
 
52
  )
53
 
54
  return router
lightrag/kg/neo4j_impl.py CHANGED
@@ -614,22 +614,19 @@ class Neo4JStorage(BaseGraphStorage):
614
  self,
615
  node_label: str,
616
  max_depth: int = 3,
617
- min_degree: int = 0,
618
- inclusive: bool = False,
619
  ) -> KnowledgeGraph:
620
  """
621
  Retrieve a connected subgraph of nodes where the label includes the specified `node_label`.
622
  Maximum number of nodes is constrained by the environment variable `MAX_GRAPH_NODES` (default: 1000).
623
  When reducing the number of nodes, the prioritization criteria are as follows:
624
- 1. min_degree does not affect nodes directly connected to the matching nodes
625
- 2. Label matching nodes take precedence
626
- 3. Followed by nodes directly connected to the matching nodes
627
- 4. Finally, the degree of the nodes
628
 
629
  Args:
630
  node_label: Label of the starting node
631
  max_depth: Maximum depth of the subgraph
632
- min_degree: Minimum degree of nodes to include. Defaults to 0
633
  inclusive: Do an inclusive search if true
634
  Returns:
635
  KnowledgeGraph: Complete connected subgraph for specified node
@@ -647,7 +644,6 @@ class Neo4JStorage(BaseGraphStorage):
647
  MATCH (n)
648
  OPTIONAL MATCH (n)-[r]-()
649
  WITH n, COALESCE(count(r), 0) AS degree
650
- WHERE degree >= $min_degree
651
  ORDER BY degree DESC
652
  LIMIT $max_nodes
653
  WITH collect({node: n}) AS filtered_nodes
@@ -660,18 +656,14 @@ class Neo4JStorage(BaseGraphStorage):
660
  """
661
  result_set = await session.run(
662
  main_query,
663
- {"max_nodes": MAX_GRAPH_NODES, "min_degree": min_degree},
664
  )
665
 
666
  else:
667
  # Main query uses partial matching
668
  main_query = """
669
  MATCH (start)
670
- WHERE
671
- CASE
672
- WHEN $inclusive THEN start.entity_id CONTAINS $entity_id
673
- ELSE start.entity_id = $entity_id
674
- END
675
  WITH start
676
  CALL apoc.path.subgraphAll(start, {
677
  relationshipFilter: '',
@@ -684,13 +676,11 @@ class Neo4JStorage(BaseGraphStorage):
684
  UNWIND nodes AS node
685
  OPTIONAL MATCH (node)-[r]-()
686
  WITH node, COALESCE(count(r), 0) AS degree, start, nodes, relationships
687
- WHERE node = start OR EXISTS((start)--(node)) OR degree >= $min_degree
688
  ORDER BY
689
  CASE
690
- WHEN node = start THEN 3
691
- WHEN EXISTS((start)--(node)) THEN 2
692
- ELSE 1
693
- END DESC,
694
  degree DESC
695
  LIMIT $max_nodes
696
  WITH collect({node: node}) AS filtered_nodes
@@ -704,11 +694,9 @@ class Neo4JStorage(BaseGraphStorage):
704
  result_set = await session.run(
705
  main_query,
706
  {
707
- "max_nodes": MAX_GRAPH_NODES,
708
  "entity_id": node_label,
709
- "inclusive": inclusive,
710
  "max_depth": max_depth,
711
- "min_degree": min_degree,
712
  },
713
  )
714
 
@@ -759,19 +747,13 @@ class Neo4JStorage(BaseGraphStorage):
759
  logger.warning(
760
  "Neo4j: falling back to basic Cypher recursive search..."
761
  )
762
- if inclusive:
763
- logger.warning(
764
- "Neo4j: inclusive search mode is not supported in recursive query, using exact matching"
765
- )
766
  return await self._robust_fallback(
767
- node_label, max_depth, min_degree
768
  )
769
 
770
  return result
771
 
772
- async def _robust_fallback(
773
- self, node_label: str, max_depth: int, min_degree: int = 0
774
- ) -> KnowledgeGraph:
775
  """
776
  Fallback implementation when APOC plugin is not available or incompatible.
777
  This method implements the same functionality as get_knowledge_graph but uses
@@ -790,7 +772,7 @@ class Neo4JStorage(BaseGraphStorage):
790
  if current_depth > max_depth:
791
  logger.debug(f"Reached max depth: {max_depth}")
792
  return
793
- if len(visited_nodes) >= MAX_GRAPH_NODES:
794
  logger.debug(f"Reached max nodes limit: {MAX_GRAPH_NODES}")
795
  return
796
 
@@ -816,8 +798,8 @@ class Neo4JStorage(BaseGraphStorage):
816
  await results.consume() # Ensure results are consumed
817
 
818
  # Nodes not connected to start node need to check degree
819
- if current_depth > 1 and len(records) < min_degree:
820
- return
821
 
822
  # Add current node to result
823
  result.nodes.append(node)
 
614
  self,
615
  node_label: str,
616
  max_depth: int = 3,
617
+ max_nodes: int = MAX_GRAPH_NODES,
 
618
  ) -> KnowledgeGraph:
619
  """
620
  Retrieve a connected subgraph of nodes where the label includes the specified `node_label`.
621
  Maximum number of nodes is constrained by the environment variable `MAX_GRAPH_NODES` (default: 1000).
622
  When reducing the number of nodes, the prioritization criteria are as follows:
623
+ 1. Label matching nodes take precedence
624
+ 2. Followed by nodes directly connected to the matching nodes
625
+ 3. Finally, the degree of the nodes
 
626
 
627
  Args:
628
  node_label: Label of the starting node
629
  max_depth: Maximum depth of the subgraph
 
630
  inclusive: Do an inclusive search if true
631
  Returns:
632
  KnowledgeGraph: Complete connected subgraph for specified node
 
644
  MATCH (n)
645
  OPTIONAL MATCH (n)-[r]-()
646
  WITH n, COALESCE(count(r), 0) AS degree
 
647
  ORDER BY degree DESC
648
  LIMIT $max_nodes
649
  WITH collect({node: n}) AS filtered_nodes
 
656
  """
657
  result_set = await session.run(
658
  main_query,
659
+ {"max_nodes": max_nodes},
660
  )
661
 
662
  else:
663
  # Main query uses partial matching
664
  main_query = """
665
  MATCH (start)
666
+ WHERE start.entity_id = $entity_id
 
 
 
 
667
  WITH start
668
  CALL apoc.path.subgraphAll(start, {
669
  relationshipFilter: '',
 
676
  UNWIND nodes AS node
677
  OPTIONAL MATCH (node)-[r]-()
678
  WITH node, COALESCE(count(r), 0) AS degree, start, nodes, relationships
 
679
  ORDER BY
680
  CASE
681
+ WHEN node = start THEN 0
682
+ ELSE length(shortestPath((start)--(node)))
683
+ END ASC,
 
684
  degree DESC
685
  LIMIT $max_nodes
686
  WITH collect({node: node}) AS filtered_nodes
 
694
  result_set = await session.run(
695
  main_query,
696
  {
697
+ "max_nodes": max_nodes,
698
  "entity_id": node_label,
 
699
  "max_depth": max_depth,
 
700
  },
701
  )
702
 
 
747
  logger.warning(
748
  "Neo4j: falling back to basic Cypher recursive search..."
749
  )
 
 
 
 
750
  return await self._robust_fallback(
751
+ node_label, max_depth, max_nodes
752
  )
753
 
754
  return result
755
 
756
+ async def _robust_fallback(self, node_label: str, max_depth: int, max_nodes: int) -> KnowledgeGraph:
 
 
757
  """
758
  Fallback implementation when APOC plugin is not available or incompatible.
759
  This method implements the same functionality as get_knowledge_graph but uses
 
772
  if current_depth > max_depth:
773
  logger.debug(f"Reached max depth: {max_depth}")
774
  return
775
+ if len(visited_nodes) >= max_nodes:
776
  logger.debug(f"Reached max nodes limit: {MAX_GRAPH_NODES}")
777
  return
778
 
 
798
  await results.consume() # Ensure results are consumed
799
 
800
  # Nodes not connected to start node need to check degree
801
+ # if current_depth > 1 and len(records) < min_degree:
802
+ # return
803
 
804
  # Add current node to result
805
  result.nodes.append(node)