Skip to content

Commit 1d8e0e0

Browse files
authored
Merge pull request #1228 from hchen2020/master
membase support
2 parents 362d486 + 7fa1ddd commit 1d8e0e0

File tree

11 files changed

+156
-20
lines changed

11 files changed

+156
-20
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace BotSharp.Abstraction.Knowledges;
2+
3+
/// <summary>
4+
/// Graph-based semantic knowledge service that supports complex relationships and connections between entities.
5+
/// This service allows for executing Cypher queries to traverse and analyze graph data structures.
6+
/// </summary>
7+
public interface ICypherGraphService
8+
{
9+
Task<GraphQueryResult> Execute(string graphId, string query, Dictionary<string, object>? args = null);
10+
11+
Task<GraphNode> MergeNode(string graphId, GraphNode node);
12+
13+
Task<bool> DeleteNode(string graphId, string nodeId);
14+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
namespace BotSharp.Abstraction.Knowledges.Models;
2+
3+
public class GraphQueryResult
4+
{
5+
public string[] Columns { get; set; } = [];
6+
public Dictionary<string, object?>[] Items { get; set; } = [];
7+
}
8+
9+
public class GraphNode
10+
{
11+
public string Id { get; set; } = string.Empty;
12+
13+
public List<string> Labels { get; set; } = new();
14+
15+
public object Properties { get; set; } = new();
16+
17+
public DateTime Time { get; set; } = DateTime.UtcNow;
18+
19+
public override string ToString()
20+
{
21+
var labelsString = Labels.Count > 0 ? string.Join(", ", Labels) : "No Labels";
22+
return $"Node ({labelsString}: {Id})";
23+
}
24+
}

src/Plugins/BotSharp.Plugin.Membase/MembasePlugin.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
1-
using BotSharp.Abstraction.Plugins;
2-
using BotSharp.Abstraction.Settings;
3-
using BotSharp.Plugin.Membase.Services;
4-
using BotSharp.Plugin.Membase.Settings;
5-
using Microsoft.Extensions.Configuration;
6-
using Microsoft.Extensions.DependencyInjection;
71
using Refit;
8-
using System.Threading.Tasks;
92

103
namespace BotSharp.Plugin.Membase;
114

@@ -29,5 +22,7 @@ public void RegisterDI(IServiceCollection services, IConfiguration config)
2922
Task.FromResult($"Bearer {dbSettings.ApiKey}")
3023
})
3124
.ConfigureHttpClient(c => c.BaseAddress = new Uri(dbSettings.Host));
25+
26+
services.AddScoped<ICypherGraphService, MembaseService>();
3227
}
3328
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace BotSharp.Plugin.Membase.Models;
2+
3+
public class CypherQueryRequest
4+
{
5+
public string Query { get; set; } = string.Empty;
6+
7+
public Dictionary<string, object> Parameters { get; set; } = [];
8+
9+
public bool IncludeExecutionPlan { get; set; } = false;
10+
11+
/// <summary>
12+
/// Whether to profile the query execution.
13+
/// </summary>
14+
public bool Profile { get; set; } = false;
15+
16+
public int? TimeoutMs { get; set; }
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace BotSharp.Plugin.Membase.Models;
2+
3+
public class CypherQueryResponse
4+
{
5+
public string[] Columns { get; set; } = [];
6+
public Dictionary<string, object?>[] Data { get; set; } = [];
7+
8+
public CypherNotification[] Notifications { get; set; } = [];
9+
public int RowCount { get; set; }
10+
}
11+
12+
public class CypherNotification
13+
{
14+
public string Code { get; set; } = string.Empty;
15+
public string Title { get; set; } = string.Empty;
16+
public string Description { get; set; } = string.Empty;
17+
}

src/Plugins/BotSharp.Plugin.Membase/Models/Node.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class Node
1313

1414
public List<string> Labels { get; set; } = new();
1515

16-
public Dictionary<string, object> Properties { get; set; } = new();
16+
public object Properties { get; set; } = new();
1717

1818
public DateTime Time { get; set; } = DateTime.UtcNow;
1919

src/Plugins/BotSharp.Plugin.Membase/Models/NodeCreationModel.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@ public class NodeCreationModel
44
{
55
public string? Id { get; set; }
66
public string[]? Labels { get; set; }
7-
public Dictionary<string, object>? Properties { get; set; }
7+
public object? Properties { get; set; }
8+
public DateTime? Time { get; set; }
89

910
public Node ToNode()
1011
{
1112
return new Node
1213
{
1314
Id = Id,
1415
Labels = Labels?.ToList() ?? new List<string>(),
15-
Properties = Properties ?? new Dictionary<string, object>(),
16-
Time = DateTime.UtcNow
16+
Properties = Properties ?? new(),
17+
Time = Time ?? DateTime.UtcNow
1718
};
1819
}
1920
}
Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
1+
using System.Text.Json;
2+
13
namespace BotSharp.Plugin.Membase.Models;
24

35
public class NodeUpdateModel
46
{
57
public string Id { get; set; } = null!;
68
public string[]? Labels { get; set; }
7-
public Dictionary<string, object>? Properties { get; set; }
9+
public object? Properties { get; set; }
10+
public DateTime? Time { get; set; }
811

912
public Node ToNode()
1013
{
1114
return new Node
1215
{
1316
Id = Id,
14-
Labels = Labels?.ToList() ?? new List<string>(),
15-
Properties = Properties ?? new Dictionary<string, object>(),
16-
Time = DateTime.UtcNow
17+
Labels = Labels?.ToList() ?? [],
18+
Properties = Properties ?? new(),
19+
Time = Time ?? DateTime.UtcNow
1720
};
1821
}
1922
}

src/Plugins/BotSharp.Plugin.Membase/Services/IMembaseApi.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,27 @@
44

55
namespace BotSharp.Plugin.Membase.Services;
66

7+
/// <summary>
8+
/// Membase REST API interface
9+
/// https://membase.dev/graph-api-reference
10+
/// </summary>
711
public interface IMembaseApi
812
{
13+
[Post("/cypher/execute?graphId={graphId}")]
14+
Task<CypherQueryResponse> CypherQueryAsync(string graphId, CypherQueryRequest request);
15+
916
[Post("/graph/{graphId}/node")]
10-
Task CreateNode(string graphId, [Body] NodeCreationModel node);
17+
Task<Node> CreateNodeAsync(string graphId, [Body] NodeCreationModel node);
1118

1219
[Get("/graph/{graphId}/node/{nodeId}")]
13-
Task<Node> GetNode(string graphId, string nodeId);
20+
Task<Node> GetNodeAsync(string graphId, string nodeId);
1421

1522
[Put("/graph/{graphId}/node/{nodeId}")]
16-
Task<Node> UpdateNode(string graphId, string nodeId, [Body] NodeUpdateModel node);
23+
Task<Node> UpdateNodeAsync(string graphId, string nodeId, [Body] NodeUpdateModel node);
24+
25+
[Put("/graph/{graphId}/node/{nodeId}/merge")]
26+
Task<Node> MergeNodeAsync(string graphId, string nodeId, [Body] NodeUpdateModel node);
1727

1828
[Delete("/graph/{graphId}/node/{nodeId}")]
19-
Task<IActionResult> DeleteNode(string graphId, string nodeId);
29+
Task<IActionResult> DeleteNodeAsync(string graphId, string nodeId);
2030
}
Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,52 @@
1+
using BotSharp.Abstraction.Knowledges;
2+
using BotSharp.Abstraction.Knowledges.Models;
3+
using BotSharp.Plugin.Membase.Models;
4+
using System.Threading.Tasks;
5+
16
namespace BotSharp.Plugin.Membase.Services;
27

3-
public class MembaseService
8+
public class MembaseService : ICypherGraphService
49
{
10+
private readonly IServiceProvider _services;
11+
private readonly IMembaseApi _membase;
12+
13+
public MembaseService(IServiceProvider services, IMembaseApi membase)
14+
{
15+
_services = services;
16+
_membase = membase;
17+
}
18+
19+
public async Task<GraphQueryResult> Execute(string graphId, string query, Dictionary<string, object>? args = null)
20+
{
21+
var response = await _membase.CypherQueryAsync(graphId, new CypherQueryRequest
22+
{
23+
Query = query,
24+
Parameters = args ?? []
25+
});
26+
27+
return new GraphQueryResult
28+
{
29+
Columns = response.Columns,
30+
Items = response.Data
31+
};
32+
}
33+
34+
public async Task<GraphNode> MergeNode(string graphId, GraphNode node)
35+
{
36+
var newNode = await _membase.MergeNodeAsync(graphId, node.Id, new NodeUpdateModel
37+
{
38+
Id = node.Id,
39+
Labels = [.. node.Labels],
40+
Properties = node.Properties,
41+
Time = node.Time
42+
});
43+
44+
return node;
45+
}
46+
47+
public async Task<bool> DeleteNode(string graphId, string nodeId)
48+
{
49+
await _membase.DeleteNodeAsync(graphId, nodeId);
50+
return true;
51+
}
552
}

0 commit comments

Comments
 (0)