MovieGraph Model - circles-arrows/blueprint41 GitHub Wiki
In this topic, you will define the MovieGraph data store model, create entities, relationships and static data.

Start by creating the default FunctionalId for the MovieGraph project.
Functional Id is responsible for generating custom unique Id for a specific entity or node. The default functional ID will be used automatically to every entity that doesnโt have its own.
Important
Always set the FunctionalIds.Default to avoid issues when running the blueprint41._
-
On the
MovieGraph.Modelproject, select the fileDatastore.cs. In theInitialmethod, the defaultFunctional Iduses guid.FunctionalIds.Default = FunctionalIds.UUID;
You can uncomment the code below to use auto-increment id instead of guid. For more details, see Functional ID.
FunctionalIds.Default = FunctionalIds.New("Shared", "SH_", IdFormat.Numeric, 0);
Note
Remove the line of code that will throw NotImplementedException.
-
Define the
Movieentity. In theInitialmethod, add new propertiestitle,taglineandreleasedof typestring. Add the new propertyUidof typeint, setnullabletofalseand set itsIndexTypetoIndexType.Unique. Set theUidproperty as the key for theMovieentity.Entities.New("Movie") .AddProperty("title", typeof(string), IndexType.Unique) .AddProperty("tagline", typeof(string)) .AddProperty("released", typeof(int)) .AddProperty("Uid", typeof(string), false, IndexType.Unique) .SetKey("Uid", true);
The
Entities.New(string)method will create the entityMovieand accepts a parameter as type string for its entity name.The
AddProperty(string, type, boolean, indexType)method accepts parameters for the property name, property type, nullability (true by default), and IndexType (None by default).Define the other entities (
PersonandGenre). Write or copy the codes below and paste it on theInitialmethod.Entities.New("Person") .AddProperty("name", typeof(string), IndexType.Unique) .AddProperty("born", typeof(int)) .AddProperty("Uid", typeof(string), false, IndexType.Unique) .SetKey("Uid", true); Entities.New("Genre") .HasStaticData(true) .AddProperty("Uid", typeof(string), false, IndexType.Unique) .SetKey("Uid", true) .AddProperty("Name", typeof(string), false);
Note
For the Genre entity, set the HasStaticData to true, so that it can contain static data.
Important
A Key is inherent to the Entity. The Entity can acquire Key from a Base class or another Entity. In the AddProperty method, you must specify its IndexType as Unique. Perform the SetKey method and pass the property name as the first argument and set the second argument as a boolean value to allow auto-generated key or not.
Warning
Neo4j has a reserved property name Id. Don't add Id as property so that it won't experience unexpected behaviours.
-
Create relationships between entities. To create a relationship between
Person(actor) andMovie, copy the codes below and paste it on theInitialmethod.Relations.New(Entities["Person"], Entities["Movie"], "ACTED_IN", "ACTED_IN") .SetInProperty("ActedMovies", PropertyType.Collection) .SetOutProperty("Actors", PropertyType.Collection) .AddProperty("roles", typeof(string[]));
The Generated classes will produce the following:
public class Person { public IEnumerable<Movie> ActedMovies { get; set; } ... } public class Movie { public IEnumerable<Person> Actors{ get; set; } ... }
๐ Note More on Generating Type-Safe Model
The
Relations.New(Entity, Entity, string, string)method will create a relationship between thePersonand theMovieentity.It accepts the following parameters:
Type Name Description Entity inEntity Source entity Entity outEntity Target entity string name Relationship name string neo4jRelationshipType Relationship name in the Neo4j database The
SetInProperty(string, PropertyType)method accepts parameters for the property name and property type in the source entity.The
SetOutProperty(string, PropertyType)method accepts parameters for the property name and property type in the target entity.The
AddProperty(string, type, boolean, indexType)method accepts parameters for the property name, property type, nullability (true by default), and IndexType (None by default).Define other relationships. Write or copy the codes below and paste it on the
Initialmethod.Relations.New(Entities["Person"], Entities["Movie"], "DIRECTED", "DIRECTED") .SetInProperty("DirectedMovies", PropertyType.Collection) .SetOutProperty("Directors", PropertyType.Collection); Relations.New(Entities["Person"], Entities["Movie"], "PRODUCED", "PRODUCED") .SetInProperty("ProducedMovies", PropertyType.Collection) .SetOutProperty("Producers", PropertyType.Collection); Relations.New(Entities["Person"], Entities["Movie"], "WROTE", "WROTE") .SetInProperty("WrittenMovies", PropertyType.Collection) .SetOutProperty("Writers", PropertyType.Collection); Relations.New(Entities["Person"], Entities["Movie"], "REVIEWED", "REVIEWED") .SetInProperty("MovieReviews", PropertyType.Collection) .AddProperty("rating", typeof(decimal), false) .AddProperty("summary", typeof(string)); Relations.New(Entities["Person"], Entities["Person"], "FOLLOWS", "FOLLOWS") .SetInProperty("FollowedPersons", PropertyType.Collection) .SetOutProperty("Followers", PropertyType.Collection); Relations.New(Entities["Movie"], Entities["Genre"], "CONTAINS_GENRE", "CONTAINS_GENRE") .SetInProperty("Genres", PropertyType.Collection);
-
Create static data for the
Genreentity. Write or copy the codes below for the creation of static data.Entities["Genre"].Refactor.CreateNode(new { Uid = "1", Name = "Action" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "2", Name = "Animation" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "3", Name = "Biography" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "4", Name = "Comedy" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "5", Name = "Documentary" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "6", Name = "Drama" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "7", Name = "Fantasy" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "8", Name = "Horror" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "9", Name = "Musical" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "10", Name = "Reality-Tv" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "11", Name = "Romance" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "12", Name = "Sci-Fi" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "13", Name = "Short" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "14", Name = "Talk-Show" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "15", Name = "Thriller" });
Important
Make sure you have set the HasStaticData to true for the Genre entity._
-
You can subscribe your event handlers in the
SubscribeEventHandlersmethod. See code below for example:Entities["Movie"].Events.OnAfterSave += (s,e) => Console.WriteLine($"Added New Movie with Uid: { e.Entity.Properties["Uid"].GetValue((OGM)s) }");
Include in usings:
using Blueprint41.Core;
-
Below is the final code for the definition of the
MovieGraphdata store model.protected void Initial() { FunctionalIds.Default = FunctionalIds.UUID; // To use auto-increment id instead of guid, use the code below instead. //FunctionalIds.Default = FunctionalIds.New("Shared", "SH_", IdFormat.Numeric, 0); Entities.New("Movie") .AddProperty("title", typeof(string)) .AddProperty("tagline", typeof(string)) .AddProperty("released", typeof(int)) .AddProperty("Uid", typeof(string), false, IndexType.Unique) .SetKey("Uid", true); Entities.New("Person") .AddProperty("name", typeof(string), IndexType.Unique) .AddProperty("born", typeof(int)) .AddProperty("Uid", typeof(string), false, IndexType.Unique) .SetKey("Uid", true); Entities.New("Genre") .HasStaticData(true) .AddProperty("Uid", typeof(string), false, IndexType.Unique) .SetKey("Uid", true) .AddProperty("Name", typeof(string), false); Relations.New(Entities["Person"], Entities["Movie"], "DIRECTED", "DIRECTED") .SetInProperty("DirectedMovies", PropertyType.Collection) .SetOutProperty("Directors", PropertyType.Collection); Relations.New(Entities["Person"], Entities["Movie"], "PRODUCED", "PRODUCED") .SetInProperty("ProducedMovies", PropertyType.Collection) .SetOutProperty("Producers", PropertyType.Collection); Relations.New(Entities["Person"], Entities["Movie"], "WROTE", "WROTE") .SetInProperty("WrittenMovies", PropertyType.Collection) .SetOutProperty("Writers", PropertyType.Collection); Relations.New(Entities["Person"], Entities["Movie"], "REVIEWED", "REVIEWED") .SetInProperty("MovieReviews", PropertyType.Collection) .AddProperty("rating", typeof(decimal), false) .AddProperty("summary", typeof(string)); Relations.New(Entities["Person"], Entities["Person"], "FOLLOWS", "FOLLOWS") .SetInProperty("FollowedPersons", PropertyType.Collection) .SetOutProperty("Followers", PropertyType.Collection); Relations.New(Entities["Movie"], Entities["Genre"], "CONTAINS_GENRE", "CONTAINS_GENRE") .SetInProperty("Genres", PropertyType.Collection); Entities["Genre"].Refactor.CreateNode(new { Uid = "1", Name = "Action" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "2", Name = "Animation" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "3", Name = "Biography" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "4", Name = "Comedy" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "5", Name = "Documentary" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "6", Name = "Drama" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "7", Name = "Fantasy" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "8", Name = "Horror" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "9", Name = "Musical" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "10", Name = "Reality-Tv" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "11", Name = "Romance" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "12", Name = "Sci-Fi" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "13", Name = "Short" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "14", Name = "Talk-Show" }); Entities["Genre"].Refactor.CreateNode(new { Uid = "15", Name = "Thriller" }); }
๐ You've successfully created and defined the MovieGraph data store model. Next topic will guide you on how to generate type-safe models based on the entity that you have created in DataStore class.