using Neo4j.Driver; using NPOI; using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Threading.Tasks; namespace Ramitta { public class Neo4jtool { private IDriver _driver; public Neo4jtool(string uri, string user, string password) { _driver = GraphDatabase.Driver(uri, AuthTokens.Basic(user, password)); } public void Close() { _driver?.Dispose(); } private string dictToLimit(Dictionary nodeProperties) { return string.Join(", ", nodeProperties.Select(prop => $"{prop.Key}: '{prop.Value.Replace("'", "\\'")}'")); } #region 增 public async Task CreateNodeAsync(string nodeType, Dictionary properties, bool alway_create = false) { using (var session = _driver.AsyncSession()) { // 通过 dictToLimit 将字典转换成条件字符串 var propertyString = dictToLimit(properties); // 构建查询语句 var query = (alway_create ? "CREATE" : "MERGE") + $" (n:{nodeType} {{{propertyString}}})"; await session.RunAsync(query); } } // 创建任意关系,支持动态定义关系类型 public enum ArrowDirection { Left, // 反向关系 Right, // 正向关系(默认) Both // 双向关系 } public async Task CreateRelationshipAsync( string relationshipType, string nodeType1, Dictionary nodeProperties1, // 使用字典替代单独的参数 string nodeType2, Dictionary nodeProperties2, // 使用字典替代单独的参数 ArrowDirection arrow = ArrowDirection.Right, Dictionary relationshipProperties = null // 可选字典参数 ){ using (var session = _driver.AsyncSession()) { // 构建查询的 MATCH 部分,动态地使用字典中的键值对来构造节点的属性 var node1Properties = string.Join(", ", nodeProperties1.Select(kv => $"{kv.Key}: \"{kv.Value}\"")); var node2Properties = string.Join(", ", nodeProperties2.Select(kv => $"{kv.Key}: \"{kv.Value}\"")); var query = $"MATCH (a:{nodeType1} {{{node1Properties}}}), (b:{nodeType2} {{{node2Properties}}}) "; // 动态构造关系属性部分 string relationshipPropertiesPart = ""; if (relationshipProperties != null && relationshipProperties.Count > 0) { var properties = string.Join(", ", relationshipProperties.Select(kv => $"{kv.Key}: \"{kv.Value}\"")); relationshipPropertiesPart = $"{{{properties}}}"; } // 根据箭头方向来决定关系的方向,并可能附加关系的属性 if (arrow == ArrowDirection.Right) query += $"MERGE (a)-[:{relationshipType} {relationshipPropertiesPart}]->(b)"; else if (arrow == ArrowDirection.Left) query += $"MERGE (b)-[:{relationshipType} {relationshipPropertiesPart}]->(a)"; else if (arrow == ArrowDirection.Both) { query += $"MERGE (a)-[:{relationshipType} {relationshipPropertiesPart}]->(b)"; query += $"MERGE (b)-[:{relationshipType} {relationshipPropertiesPart}]->(a)"; } // 执行查询 await session.RunAsync(query); } } #endregion #region 查 // 寻找指定节点 // await neo4jService.GetRelatedNodesAsync("文件", properties); public async Task>> GetRelatedNodesAsync( string nodeLabel, Dictionary? nodeProperties=null) { string query; if (nodeProperties == null) { query = $@" MATCH (h:{nodeLabel})-[r]-(related) RETURN DISTINCT h,related"; } else { query = $@" MATCH (h:{nodeLabel} {{{dictToLimit(nodeProperties)}}})-[r]-(related) RETURN DISTINCT h,related"; } var resultList = new List>(); using (var session = _driver.AsyncSession()) { var result = await session.RunAsync(query); await result.ForEachAsync(record => { var hNode = record["h"].As(); var dict = new Dictionary(); // 添加所有属性 foreach (var property in hNode.Properties) { dict[property.Key] = property.Value?.ToString() ?? string.Empty; } resultList.Add(dict); }); } return resultList; } public async Task> slavenode( string nodeLabel, Dictionary? nodeProperties = null) { string query; if (nodeProperties == null) { query = $@" MATCH (h:{nodeLabel})-[r]-(related) RETURN DISTINCT h,r,related"; } else { query = $@" MATCH (h:{nodeLabel} {{{dictToLimit(nodeProperties)}}})-[r]-(related) RETURN DISTINCT h,r,related"; } var resultList = new List<(INode h, IRelationship r, INode related)>(); using (var session = _driver.AsyncSession()) { var result = await session.RunAsync(query); await result.ForEachAsync(record => { var hNode = record["h"].As(); var rRelation = record["r"].As(); var relatedNode = record["related"].As(); // 将h, r, related 作为元组加入结果列表 resultList.Add((hNode, rRelation, relatedNode)); }); } return resultList; } #endregion #region 删 public async Task DeleteNodeAsync(string nodeType, Dictionary nodeProperties) { using (var session = _driver.AsyncSession()) { // 构建查询条件 var queryConditions = string.Join(" AND ", nodeProperties.Keys.Select(k => $"n.{k} = ${k}")); // 运行查询并传递字典参数 await session.RunAsync( $"MATCH (n:{nodeType}) WHERE {queryConditions} DETACH DELETE n", nodeProperties ); } } // 删除所有节点和关系 public async Task DeleteAllNodesAndRelationshipsAsync() { using (var session = _driver.AsyncSession()) { await session.RunAsync("MATCH (n) DETACH DELETE n"); } } #endregion } }