Alex Popescu, author of the well-known MyNoSQL blog recently wrote about a very (very) basic tag­ging app and its imple­men­ta­tion within the Info­Grid and Neo4j graph data­base systems.

Today we want to pick up the given exam­ple and show you an imple­men­ta­tion using the sones GraphDB and the GraphDB­Sharp API:


using System;
using System.Linq;
using System.Collections.Generic;

using sones.GraphDB;
using sones.GraphDB.Structures;
using sones.GraphDB.API.CSharp;
using sones.GraphDB.API.CSharp.Reflection;
using sones.GraphDB.Connectors.GraphDBREST;
using sones.GraphFS.Connectors.GraphFSCLI;
using sones.GraphDB.Connectors.GraphDBCLI;

namespace TagExample
{

    public class Tag : DBObject {

        // Will inherit an UUID and RevisionID property from DBObject

        [CreateIndex(DBIndexTypes.HashTable)]
        public String Name { get; set; }

        // Backwardedges to the attribute Tags of type Websites
        [BackwardEdge("Tags")]
        public List<Website> TaggedWebsites { get; set; }

        public Tag() { }

    }

    public class Website : DBObject
    {

        // Will inherit an UUID and RevisionID property from DBObject

        [CreateIndex(DBIndexTypes.HashTable)]
        public String Name { get; set; }

        public String URL  { get; set; }

        // Edges to the tags
        public List<Tag> Tags { get; set; }

        public Website() { }

    }

    public class TagExample
    {

        private void CheckResult(QueryResult myQueryResult)
        {
            Console.WriteLine("{0} => {1}",
                myQueryResult.Query,
                myQueryResult.ResultType);
        }

        private void Run()
        {

            // Create a new in-memory database
            var GDB = new GraphDBSharp()
            {
                DatabaseName        = "TagExampleDB",
                Username            = "Dr.Falken",
                Password            = "Joshua"
                // For persistence use:
                //StorageLocation   = "file://TagExampleDB.fs",
                //StorageLocation   = "net.tcp://127.0.0.1:8000",
            };

            GDB.CreateDatabase(true);

            // Create types tag and website using reflection
            GDB.CreateTypes(CheckResult, new Tag(), new Website());

            // Insert tags
            var _good  = new Tag() { Name = "good"  };
            var _funny = new Tag() { Name = "funny" };
            GDB.Insert(CheckResult, _good, _funny);

            // Insert websites and link them to their tags
            var _cnn   = new Website() {
                            Name = "CNN",
                            URL  = "http://cnn.com/",
                            Tags = new List<Tag>() { _good }
                         };

            var _xkcd  = new Website() {
                            Name = "xkcd",
                            URL  = "http://xkcd.com/",
                            Tags = new List<Tag>() { _good, _funny }
                         };

            var _onion = new Website() {
                            Name = "onion",
                            URL  = "http://theonion.com/",
                            Tags = new List<Tag>() { _funny }
                         };

            GDB.Insert(CheckResult, _cnn, _xkcd, _onion);

            // Find out which tags xkcd is tagged with
            var _xkcdtags = GDB.Query("FROM Website w SELECT w.Tags " +
                                      "WHERE w.Name = 'xkcd' DEPTH 1");
            foreach (var _tag in (List<DBObjectReadout>) _xkcdtags["Tags"])
                Console.WriteLine(_tag["Name"]);

            // List tagged sites
            var _taggedsites = GDB.Query("FROM Website w SELECT w.Name, " +
                                         "Count(w.Tags) AS Counter " +
                                         "WHERE Count(w.Tags)>0");
            foreach (var _sites in (List<DBObjectReadout>) _taggedsites[0])
                Console.WriteLine("{0} => {1}", _sites["Name"], _sites["Counter"]);

            // Start a REST service on localhost port 9975
            GDB.StartREST(new Uri("http://localhost:9975"));

            // Start the GraphDB command line interface
            GDB.OpenCLI(typeof(ABasicFSCLICommands),
                        typeof(AAdvancedFSCLICommands),
                        typeof(ABasicDBCLICommands),
                        typeof(AAdvancedDBCLICommands));

            GDB.Shutdown();

        }

        public static void Main(string[] myArgs)
        {
            var w = new TagExample();
            w.Run();
        }

    }

}

 

The cur­rent C# API is already very expres­sive, but other pro­gram­ming lan­guages might be much more ver­bose. To avoid writ­ing a lot of code, you can always use our Graph Query Lan­u­age (GQL) which is an opti­mized Domain-specific lan­guage (DSL) for cre­at­ing and manip­u­lat­ing a graph within our database.


  CREATE TYPES
    Tag EXTENDS DBObject
        ATTRIBUTES (String Name)
        BACKWARDEDGES (Website.Tags TaggedWebsites)
        INDICES (Name),
    Website EXTENDS DBObject
        ATTRIBUTES (String Name, String URL, LIST<Tag> Tags)
        INDICES (Name)

  INSERT INTO Tag VALUES (Name = 'good')
  INSERT INTO Tag VALUES (Name = 'funny')

  INSERT INTO Website VALUES
    (Name = 'CNN',
     URL  = 'http://cnn.com/',
     Tags = SETOF (Name = 'good'))

  INSERT INTO Website VALUES
    (Name = 'xkcd',
     URL  = 'http://xkcd.com/',
     Tags = SETOF (Name = 'good', Name = 'funny'))

  INSERT INTO Website VALUES
    (Name = 'onion',
     URL  = 'http://theonion.com/',
     Tags = SETOF (Name = 'funny'))

  // Find out which tags xkcd is tagged with...
  FROM Website w SELECT w.Tags WHERE w.Name = 'xkcd' DEPTH 1
  // Alternative query...
  FROM Tag     t SELECT t.Name WHERE t.TaggedWebsites.Name = 'xkcd'

  // List tagged sites...
  FROM Website w SELECT w.Name, Count(w.Tags) AS Counter WHERE Count(w.Tags)>0