RE: [External] [xdi] One change to multiplicity proposal

From
Barnhill, William [USA] <>
Date
2012-09-28T18:56:51+00:00
ID
Thread
RE: [External] [xdi] One change to multiplicity proposal
Some thoughts for our query language are below.  These are taken from a comparison  of two Neo4j graph query languages, Cypher and Gremlin, posted at

http://romikoderbynew.com/2012/02/22/gremlin-vs-cypher-initial-thoughts-neo4j/.

 

Simple graph traversals are much more efficient when using Gremlin

Queries in Gremlin are 30-50% faster for simple traversals

Cypher is ideal for complex traversals where back tracking is required

Cypher is our choice of query language for reporting

Gremlin is our choice of query language for simple traversals where projections are not required

Cypher has intrinsic table projection model, where Gremlins table projection model relies on AS steps which can be cumbersome when backtracking e.g. Back(), As() and
_CopySplit, where cypher is just comma separated matches

Cypher is much better suited for outer joins than Gremlin, to achieve similar results in gremlin requires parallel querying with CopySplit, where as in Cypher using the Match clause with

optional relationships

Gremlin is ideal when you need to retrieve very simple data structures

Table projection in gremlin can be very powerful, however outer joins can be very verbose

An example of Cypher

var resultSet = graphClient.RootNode

                .StartCypher("root")

                .Match(@"root-[:HOSTS]->(agency)

                       <-[:USER_BELONGS_TO]-(user)-[:USER_LINKED_TO_PROGRAM]

                       ->(program)

                       <-[:HAS_PROGRAM]-(centre),

                       (program)<-[:HAS_SUGGESTED_PROGRAM]-(referralDecisionsSection)

                       <-[:REFERRAL_HAS_DECISIONS_SECTION]-(referral)-[:CREATED_BY]

                       ->(createdByUser), (referral)-[:REFERRAL_HAS_WHO_SECTION]

                       ->(whoSection)-[:HAS_PARTICIPANT]->(participant)")

                .Where<Agency>(agency => agency.Key == userIdentifier.AgencyKey)

                .And()

                .Where<User>(user => user.Username == userIdentifier.Username)

                .And()

                .Where<Referral>(referral => referral.Completed == false)

                .Return((user, program, centre, createdByUser, referral, whoSection, participant) =>

                new ReferralByGroup

                {

                    UserFamilyName = createdByUser.As<User>().FamilyName,

                    UserGivenName = createdByUser.As<User>().GivenName,

                    Program = program.As<Program>().Name,

                    Centre = centre.As<Centre>().Name,

                    ReferralId = referral.As<Referral>().UniqueId,

                    ReferralDate = whoSection.As<ReferralWhoSection>().ReferralDate,

                    ParticipantName = participant.As<ReferralParticipant>().Name,

                    ParticipantDisplayOrder = participant.As<ReferralParticipant>().DisplayOrder,

                })

                .Results

                .ToArray();

 

An equivalent in Gremlin:

var resultSet = graphClient

    .RootNode

    .Out<Agency>(Hosts.TypeKey, a => a.Key == userIdentifier.AgencyKey)

    .In<User>(UserBelongsTo.TypeKey, u => u.Username == userIdentifier.Username)

    .Out<Program>(UserLinkedToProgram.TypeKey)

    .As("Program")

    .In<Centre>(HasProgram.TypeKey)

   .As("Centre")

    .BackV<Program>("Program")

    .In<ReferralDecisionsSection>(HasSuggestedProgram.TypeKey)

    .In<Referral>(ReferralHasDecisionsSection.TypeKey, r => r.Completed == false)

    .As("ReferralId")

    .Out<User>(CreatedBy.TypeKey)

    .As("UserGivenName")

    .As("UserFamilyName")

    .BackV<Referral>("ReferralId")

    .Out<ReferralWhoSection>(ReferralHasWhoSection.TypeKey)

    .As("ReferralDate")

    .Out<ReferralParticipant>(HasParticipant.TypeKey)

    .As("ParticipantDisplayOrder")

    .As("ParticipantName")

    .Table

    <ReferralByGroup, Program, Centre, Referral, User, User, ReferralWhoSection, ReferralParticipant,

        ReferralParticipant>(

            program => program.Name,

            centre => centre.Name,

            referral => referral.UniqueId,

            user => user.FamilyName,

            user => user.GivenName,

            who => who.ReferralDate,

            participant => participant.Name,

            participant => participant.DisplayOrder

    )

    .ToArray();

 

And I will try to post a follow-up email with an equivalent in XGP, XDI Graph Patterns, the query language I’ve been trying to put together as an underpinning
 for applying DLP style reasoning to an XDI dataset, similar to what Euler# allows for semantic web queries.

 

 

 

Kind regards,

 

Bill Barnhill

Booz Allen Hamilton - Belcamp,MD



Cell: 1-443-924-0824

Desk: 1-443-861-9102