routes.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. """
  2. Graph API module
  3. 提供图数据库操作的API接口
  4. """
  5. import logging
  6. from flask import jsonify, request
  7. from app.api.graph import bp
  8. from app.core.graph import (
  9. create_or_get_node,
  10. create_relationship,
  11. execute_cypher_query,
  12. get_subgraph,
  13. )
  14. from app.models.result import failed, success
  15. logger = logging.getLogger("app")
  16. # 查询图数据
  17. @bp.route("/query", methods=["POST"])
  18. def query_graph():
  19. """
  20. 执行自定义Cypher查询
  21. Args (通过JSON请求体):
  22. cypher (str): Cypher查询语句
  23. params (dict, optional): 查询参数
  24. Returns:
  25. JSON: 包含查询结果的响应
  26. """
  27. try:
  28. # 获取查询语句
  29. cypher = request.json.get("cypher", "") if request.json is not None else ""
  30. params = request.json.get("params", {}) if request.json is not None else {}
  31. if not cypher:
  32. return jsonify(failed("查询语句不能为空"))
  33. # 执行查询
  34. data = execute_cypher_query(cypher, params)
  35. return jsonify(success(data))
  36. except Exception as e:
  37. logger.error(f"图数据查询失败: {str(e)}")
  38. return jsonify(failed(str(e)))
  39. # 创建节点
  40. @bp.route("/node/create", methods=["POST"])
  41. def create_node():
  42. """
  43. 创建新节点
  44. Args (通过JSON请求体):
  45. labels (list): 节点标签列表
  46. properties (dict): 节点属性
  47. Returns:
  48. JSON: 包含创建的节点信息的响应
  49. """
  50. try:
  51. # 获取节点信息
  52. labels = request.json.get("labels", []) if request.json is not None else []
  53. properties = (
  54. request.json.get("properties", {}) if request.json is not None else {}
  55. )
  56. if not labels:
  57. return jsonify(failed("节点标签不能为空"))
  58. # 构建标签字符串
  59. label = ":".join(labels)
  60. # 创建节点
  61. node_id = create_or_get_node(label, **properties)
  62. # 查询创建的节点
  63. cypher = f"MATCH (n) WHERE id(n) = {node_id} RETURN n"
  64. result = execute_cypher_query(cypher)
  65. if result and len(result) > 0:
  66. return jsonify(success(result[0]))
  67. else:
  68. return jsonify(failed("节点创建失败"))
  69. except Exception as e:
  70. logger.error(f"创建节点失败: {str(e)}")
  71. return jsonify(failed(str(e)))
  72. # 创建关系
  73. @bp.route("/relationship/create", methods=["POST"])
  74. def create_rel():
  75. """
  76. 创建节点间的关系
  77. Args (通过JSON请求体):
  78. startNodeId (int): 起始节点ID
  79. endNodeId (int): 结束节点ID
  80. type (str): 关系类型
  81. properties (dict, optional): 关系属性
  82. Returns:
  83. JSON: 包含创建的关系信息的响应
  84. """
  85. try:
  86. # 获取关系信息
  87. start_node_id = (
  88. request.json.get("startNodeId") if request.json is not None else None
  89. )
  90. end_node_id = (
  91. request.json.get("endNodeId") if request.json is not None else None
  92. )
  93. rel_type = request.json.get("type") if request.json is not None else None
  94. properties = (
  95. request.json.get("properties", {}) if request.json is not None else {}
  96. )
  97. if not all([start_node_id, end_node_id, rel_type]):
  98. return jsonify(failed("关系参数不完整"))
  99. # 创建关系
  100. rel_id = create_relationship(start_node_id, end_node_id, rel_type, **properties)
  101. if rel_id:
  102. # 查询创建的关系
  103. cypher = f"MATCH ()-[r]-() WHERE id(r) = {rel_id} RETURN r"
  104. result = execute_cypher_query(cypher)
  105. if result and len(result) > 0:
  106. return jsonify(success(result[0]))
  107. return jsonify(failed("关系创建失败"))
  108. except Exception as e:
  109. logger.error(f"创建关系失败: {str(e)}")
  110. return jsonify(failed(str(e)))
  111. # 获取图谱数据
  112. @bp.route("/subgraph", methods=["POST"])
  113. def get_graph_data():
  114. """
  115. 获取子图数据
  116. Args (通过JSON请求体):
  117. nodeIds (list): 节点ID列表
  118. relationshipTypes (list, optional): 关系类型列表
  119. maxDepth (int, optional): 最大深度,默认为1
  120. Returns:
  121. JSON: 包含节点和关系的子图数据
  122. """
  123. try:
  124. # 获取请求参数
  125. node_ids = request.json.get("nodeIds", []) if request.json is not None else []
  126. rel_types = (
  127. request.json.get("relationshipTypes", [])
  128. if request.json is not None
  129. else []
  130. )
  131. max_depth = request.json.get("maxDepth", 1) if request.json is not None else 1
  132. if not node_ids:
  133. return jsonify(failed("节点ID列表不能为空"))
  134. # 获取子图
  135. graph_data = get_subgraph(node_ids, rel_types, max_depth)
  136. return jsonify(success(graph_data))
  137. except Exception as e:
  138. logger.error(f"获取图谱数据失败: {str(e)}")
  139. return jsonify(failed(str(e)))