Skip to content

MovieGraph Model

Link edited this page Apr 25, 2024 · 17 revisions

Defining the MovieGraph model

In this topic, you will define the MovieGraph data store model, create entities, relationships and static data.

image

Start by creating the default FunctionalId for the MovieGraph project.

Functional ID

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._

  1. On the MovieGraph.Model project, select the file Datastore.cs. In the Initial method, the default Functional Id uses 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.

Entities

  1. Define the Movie entity. In the Initial method, add new properties title, tagline and released of type string. Add the new property Uid of type int, set nullable to false and set its IndexType to IndexType.Unique. Set the Uid property as the key for the Movie entity.

    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 entity Movie and 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 (Person and Genre). Write or copy the codes below and paste it on the Initial method.

    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.

Relationships

  1. Create relationships between entities. To create a relationship between Person (actor) and Movie, copy the codes below and paste it on the Initial method.

    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 the Person and the Movie entity.

    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 Initial method.

    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);

Static Data

  1. Create static data for the Genre entity. 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._

Event Handlers (Optional)

  1. You can subscribe your event handlers in the SubscribeEventHandlers method. 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;

Movie Graph Model

  1. Below is the final code for the definition of the MovieGraph data 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.