Giter VIP home page Giter VIP logo

exram.gremlinq's Introduction

Gremlinq mascot

ExRam.Gremlinq is a .NET object-graph-mapper for Apache TinkerPop™ Gremlin enabled databases.

Build status

Packages

Package Stable Preview
ExRam.Gremlinq.Core # #
ExRam.Gremlinq.Providers.WebSocket # #
ExRam.Gremlinq.Providers.GremlinServer # #
ExRam.Gremlinq.Providers.CosmosDb # #
ExRam.Gremlinq.Providers.Neptune # #
ExRam.Gremlinq.Providers.JanusGraph # #
ExRam.Gremlinq.Core.AspNet # #
ExRam.Gremlinq.Providers.WebSocket.AspNet # #
ExRam.Gremlinq.Providers.GremlinServer.AspNet # #
ExRam.Gremlinq.Providers.CosmosDb.AspNet # #
ExRam.Gremlinq.Providers.Neptune.AspNet # #
ExRam.Gremlinq.Providers.JanusGraph.AspNet # #

Sample project

A sample project can be found at https://github.com/ExRam/ExRam.Gremlinq.Samples.

Commercial support

For commercial support, contact
#

Features

The following snippets are part of the sample project mentioned above. They showcase some of the many features of ExRam.Gremlinq.

Easily create vertices and edges

    var marko = await _g
        .AddV(new Person { Name = "Marko", Age = 29 })
        .FirstAsync();

    var vadas = await _g
        .AddV(new Person { Name = "Vadas", Age = 27 })
        .FirstAsync();
            
    var josh = await _g
        .AddV(new Person { Name = "Josh", Age = 32 })
        .FirstAsync();

    var peter = await _g
        .AddV(new Person { Name = "Peter", Age = 35 })
        .FirstAsync();

    var daniel = await _g
        .AddV(new Person
        {
            Name = "Daniel",
            Age = 37,
            PhoneNumbers = new []
            {
                "+491234567",
                "+492345678"
            }
        })
        .FirstAsync();

    var charlie = await _g
        .AddV(new Dog { Name = "Charlie", Age = 2 })
        .FirstAsync();

    var catmanJohn = await _g
        .AddV(new Cat { Name = "Catman John", Age = 5 })
        .FirstAsync();

    var luna = await _g
        .AddV(new Cat { Name = "Luna", Age = 9 })
        .FirstAsync();

    var lop = await _g
        .AddV(new Software { Name = "Lop", Language = ProgrammingLanguage.Java })
        .FirstAsync();

    var ripple = await _g
        .AddV(new Software { Name = "Ripple", Language = ProgrammingLanguage.Java })
        .FirstAsync();

    await _g
        .V(_marko.Id)
        .AddE<Knows>()
        .To(__ => __
            .V(vadas.Id))
        .FirstAsync();

    await _g
        .V(_marko.Id)
        .AddE<Knows>()
        .To(__ => __
            .V(josh.Id))
        .FirstAsync();

    await _g
        .V(_marko.Id)
        .AddE<Created>()
        .To(__ => __
            .V(lop.Id))
        .FirstAsync();

    await _g
        .V(josh.Id)
        .AddE<Created>()
        .To(__ => __
            .V(ripple.Id))
        .FirstAsync();

    await _g
        .V(josh.Id)
        .AddE<Created>()
        .To(__ => __
            .V(lop.Id))
        .FirstAsync();

    await _g
        .V(peter.Id)
        .AddE<Created>()
        .To(__ => __
            .V(lop.Id))
        .FirstAsync();

    await _g
        .V(josh.Id)
        .AddE<Owns>()
        .To(__ => __
            .V(charlie.Id))
        .FirstAsync();

    await _g
        .V(josh.Id)
        .AddE<Owns>()
        .To(__ => __
            .V(luna.Id))
        .FirstAsync();

    await _g
        .V(daniel.Id)
        .AddE<Owns>()
        .To(__ => __
            .V(catmanJohn.Id))
        .FirstAsync();

    // Add Persons and and edge in between in one single query!
    await _g
        .AddV(new Person { Name = "Bob", Age = 36 })
        .AddE<Knows>()
        .To(__ => __
            .AddV(new Person { Name = "Jeff", Age = 27 }))
        .FirstAsync();

Build nice queries

From marko, walk all the Knows edges to all the Persons that he knows and order them by their names:

    var peopleKnownToMarko = await _g
        .V(marko.Id)
        .Out<Knows>()
        .OfType<Person>()
        .Order(_ => _
            .By(x => x.Name))
        .Values(x => x.Name)
        .ToArrayAsync();


Gremlinq supports boolean expressions like you're used to use them in your Linq-queries. Under the hood, they will be translated to the corresponding Gremlin-expressions, like

g.V().hasLabel('Person').has('Age', gt(30))

in this case:

    var peopleOlderThan30 = await _g
        .V<Person>()
        .Where(x => x.Age > 30)
        .ToArrayAsync();


Even an expression like 'StartsWith' on a string will be recognized by ExRam.Gremlinq and translated to proper Gremlin syntax:

    var nameStartsWithB = await _g
        .V<Person>()
        .Where(x => x.Name.Value.StartsWith("B"))
        .ToArrayAsync();


Here, we demonstrate how to deal with Gremlin step labels. Instead of dealing with raw strings, ExRam.Gremlinq uses a dedicated StepLabel-type for these. And you don't even need to declare them upfront, as the As-operator of ExRam.Gremlinq will put them in scope for you, along with a continuation-query that you can further build upon! Also, ExRam.Gremlinq's Select operators will not leave you with raw dictionaries (or maps, as Java calls them). Instead, you'll get nice ValueTuples!

    var friendTuples = await _g
        .V<Person>()
        .As((__, person) => __
            .Out<Knows>()
            .OfType<Person>()
            .As((__, friend) => __
                .Select(person, friend)));


ExRam.Gremlinq supports inheritance! Below query will find all the dogs and all the cats and instantiate the right type.

    var pets = await _g
        .V<Pet>();


This sample demonstrates how to fluently build projections with ExRam.Gremlinq. It can project to a ValueTuple or to a dynamic. In the latter case, the user may specify the name of each projection.

    var dynamics = await _g
        .V<Person>()
        .Project(b => b
            .ToDynamic()
            .By(person => person.Name)
            .By(
                "count",
                __ => __
                    .Cast<object>()
                    .Out<Owns>()
                    .OfType<Pet>()
                    .Count()));


ExRam.Gremlinq supports multi-properties! And since these are represented on the POCOs as arrays (in this case PhoneNumbers), you want to call things like Contain on them! ExRam.Gremlinq recognizes these expressions!

    var personWithThatPhoneNumber = await _g
        .V<Person>()
        .Where(person => person
            .PhoneNumbers
            .Contains("+491234567"))
        .FirstOrDefaultAsync();


Group also has a beautiful fluent interface!

    var entityGroups = await _g
       .V()
       .Group(g => g
           .ByKey(__ => __.Label())
           .ByValue(__ => __.Count()))
       .FirstAsync();


This showcases the power of the fluent interface of ExRam.Gremlinq. Once we go from a Person to the Created edge, the entity we came from is actually encoded in the interface, so on calling OutV, ExRam.Gremlinq remembers that we're now on a Person again.

    var creators = await _g
        .V<Person>()
        .OutE<Created>()
        .OutV()
        .Dedup();


ExRam.Gremlinq even defines extension methods on StepLabels so you can ask question like the following: Which persons have an age that's within a previously collected set of ages, referenced by a step label? So first, for simplicity, we inject 3 values (29, 30, 31), fold them and store them in a step label 'ages'. Note that these values 29, 30 and 31 don't need to be hard coded but can come from an ordinary traversal. Then, we ask for all the persons whose age is contained within the array that the 'ages' step label references.

    var personsWithSpecificAges = await _g
        .Inject(29, 30, 31)
        .Fold()
        .As((_, ages) => _
            .V<Person>()
            .Where(person => ages.Contains(person.Age)));


Finally, we demonstrate setting and retrieving properties on vertex properties. Furthermore, we show how to dynamically avoid queries if the underlying graph database provider doesn't support them. The following code will not run on AWS Neptune since it doesn't support meta properties.

    if (_g.Environment.FeatureSet.Supports(VertexFeatures.MetaProperties))
    {
        await _g
            .V<Person>(_marko.Id)
            .Properties(x => x.Name)
            .Property(x => x.Creator, "Stephen")
            .Property(x => x.Date, DateTimeOffset.Now)
            .ToArrayAsync();

        var metaProperties = await _g
            .V()
            .Properties()
            .Properties()
            .ToArrayAsync();
    }

Provider bindings

exram.gremlinq's People

Contributors

danielcweber avatar syntaxunknown avatar simoncropp avatar github-actions[bot] avatar gabi-giladov avatar javaadpatel avatar koenbeuk avatar dependabot[bot] avatar ksemenenko avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.