As I continued work on BrainExpanded and its MCP service, I came to realize that I needed support for dynamic entities and full text search in the Graph Model API. I just published a new release of the Cvoya Graph Model packages with many changes. Here’s a summary:
DynamicNode and DynamicRelationship types provide the necessary support.PropertyAttribute has been updated to support options related to full text search (e.g. IncludeInFullTextSearch) or to schema-related requirements (e.g. IsRequired, IsUnique).Cvoya.Graph.Model.Neo4j package to your project. The necessary package dependencies will be included and the code generator will be automatically activated at build time of your project. The Cvoya.Graph.Model.Analyzers package is still optional but recommended.You can now use DynamicNode and DynamicRelationship for nodes and relationships:
// Create a node
var node = new DynamicNode(
labels: new[] { "Person" },
properties: new Dictionary<string, object?>
{
["name"] = "John Doe",
["age"] = 40,
["email"] = "john@example.com",
["active"] = true
}
);
await Graph.CreateNodeAsync(node);
It’s similar for relationships.
You can configure the properties using the introduced PropertyConfiguration-related API. Refer to the source code on github for more details. When I get some time, I will write an example and update the documentation.
Of course, it is possible to interact with the created node using a strong type:
public record Person : Node
{
[Property(Label = "name")]
public string FullName { get; set; }
[Property(Label = "age")]
public int Age { get; set; }
[Property(Label = "email")]
public string Email { get; set; }
[Property(Label = "active")]
public bool IsActive { get; set; }
}
var person = await graph.Nodes<Person>()
.Where(p => p.Id = "...")
.FirstOrDefaultAsync();
Every entity (node or relationship) with a string property is automatically added to the text index unless otherwise configured. There is a text index per property and a global one. You can search the global index using Search(), node/relationship indexes using SearchNodes() and SearchRelationships, or type-specific indexes using SearchNodes<Person>() and SearchRelationships<FriendsWith>(). You can then compose the search operators with other LINQ queries:
var johnsOver30 = await graph
.SearchNode<Person>("John")
.Where(p => p.Age > 30)
.ToListAsync()
And now, it’s much easier to get started:
> dotnet new console
> dotnet add package Cvoya.Graph.Model.Neo4j -v 1.0.0-alpha.20250716.4
# optionally but recommended
> dotnet add package Cvoya.Graph.Model.Analyzers -v 1.0.0-alpha.20250716.4
Happy coding!
There’s a unique energy that comes with starting something new — a blend of excitement,…
Just over a month ago, I published "Playing with graphs and Neo4j". Back then, it…
After my initial implementation of some BrainExpanded-related ideas on top of dgraph using its GraphQL…
Say hello to the Graph Model Domain Specific Language (GMDSL), created with the help of…
As I wrote in previous posts, the manual recording of memories for BrainExpanded is just…
Imagine a world where your memory is enhanced by a team of intelligent agents, working…