日常更新
This commit is contained in:
203
Ramitta/Database/Neo4j.cs
Normal file
203
Ramitta/Database/Neo4j.cs
Normal file
@@ -0,0 +1,203 @@
|
||||
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<string, string> nodeProperties)
|
||||
{
|
||||
return string.Join(", ", nodeProperties.Select(prop => $"{prop.Key}: '{prop.Value.Replace("'", "\\'")}'"));
|
||||
}
|
||||
|
||||
|
||||
#region 增
|
||||
public async Task CreateNodeAsync(string nodeType, Dictionary<string, string> 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<string, string> nodeProperties1, // 使用字典替代单独的参数
|
||||
string nodeType2, Dictionary<string, string> nodeProperties2, // 使用字典替代单独的参数
|
||||
ArrowDirection arrow = ArrowDirection.Right,
|
||||
Dictionary<string, string> 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<List<Dictionary<string, string>>> GetRelatedNodesAsync(
|
||||
string nodeLabel,
|
||||
Dictionary<string, string>? 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<Dictionary<string, string>>();
|
||||
using (var session = _driver.AsyncSession())
|
||||
{
|
||||
var result = await session.RunAsync(query);
|
||||
await result.ForEachAsync(record =>
|
||||
{
|
||||
var hNode = record["h"].As<INode>();
|
||||
var dict = new Dictionary<string, string>();
|
||||
// 添加所有属性
|
||||
foreach (var property in hNode.Properties)
|
||||
{
|
||||
dict[property.Key] = property.Value?.ToString() ?? string.Empty;
|
||||
}
|
||||
resultList.Add(dict);
|
||||
});
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task<List<(INode h, IRelationship r, INode related)>> slavenode(
|
||||
string nodeLabel,
|
||||
Dictionary<string, string>? 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<INode>();
|
||||
var rRelation = record["r"].As<IRelationship>();
|
||||
var relatedNode = record["related"].As<INode>();
|
||||
|
||||
// 将h, r, related 作为元组加入结果列表
|
||||
resultList.Add((hNode, rRelation, relatedNode));
|
||||
});
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 删
|
||||
public async Task DeleteNodeAsync(string nodeType, Dictionary<string, string> 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
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user