Degree hops in AWS Neptune RDF Format

0

I have loaded data in aws neptune in rdf format and Now I am querying data with neptune notebook using %%sparql magic command ..In this I want to run degree hops *3..10 like this how can I achieve this in sparql in aws neptune.

asked 8 months ago201 views
1 Answer
1
Accepted Answer

SPARQL has a feature called Property Paths that allows you to define the number of hops taken across a given predicate ("edge"). https://www.w3.org/TR/sparql11-property-paths/

One thing to note, however, is that SPARQL does not natively support the return of paths. A Property Path query will only return the results found at the end of path. You would need to execute these queries for each level and UNION the results in order to fetch all "connected components" within a certain number of hops.

Updated: Sep 7th 9:23am US/Eastern

If you wanted to do something like the following from openCypher:

MATCH p= (investor1: Investor {name: 'XYZ'}) - [ : HAS_EMAIL | HAS_PHONE | HAS_PRIMARY_CONTACT | HQ_ FAX*.. 10]-(Investor2:Investor)
WHERE investor1<>investor2
RETURN p

It would look something like this in SPARQL with the following sample dataset:

INSERT DATA {
    <investor:aaa> <dataProp:name> "XYZ" .
    <investor:aaa> <objProp:HAS_EMAIL> <email:xyz-at-nobody-dot-com> .
    <investor:aaa> <objProp:HAS_PHONE> <phone:555-555-1111> .
    <investor:aaa> <objProp:HAS_PRIMARY_CONTACT> <pcontact:some-info-abc> .
    <investor:aaa> <objProp:HAS_FAX> <fax:555-555-9991> .
    <investor:bbb> <dataProp:name> "ABC" .
    <investor:bbb> <objProp:HAS_EMAIL> <email:abc-at-nobody-dot-com> .
    <investor:bbb> <objProp:HAS_PHONE> <phone:555-555-1111> .
    <investor:bbb> <objProp:HAS_PRIMARY_CONTACT> <pcontact:some-info-abc> .
    <investor:bbb> <objProp:HAS_FAX> <fax:555-555-9992> .
    <investor:ccc> <dataProp:name> "DEF" .
    <investor:ccc> <objProp:HAS_EMAIL> <email:def-at-nobody-dot-com> .
    <investor:ccc> <objProp:HAS_PHONE> <phone:555-555-1112> .
    <investor:ccc> <objProp:HAS_PRIMARY_CONTACT> <pcontact:some-info-def> .
    <investor:ccc> <objProp:HAS_FAX> <fax:555-555-9992> .
    <investor:ddd> <dataProp:name> "GHI" .
    <investor:ddd> <objProp:HAS_EMAIL> <email:ghi-at-nobody-dot-com> .
    <investor:ddd> <objProp:HAS_PHONE> <phone:555-555-1112> .
    <investor:ddd> <objProp:HAS_PRIMARY_CONTACT> <pcontact:some-info-def> .
    <investor:ddd> <objProp:HAS_FAX> <fax:555-555-9994> .
    <investor:eee> <dataProp:name> "JKL" .
    <investor:eee> <objProp:HAS_EMAIL> <email:jkl-at-nobody-dot-com> .
    <investor:eee> <objProp:HAS_PHONE> <phone:555-555-1113> .
    <investor:eee> <objProp:HAS_PRIMARY_CONTACT> <pcontact:some-info-abc> .
    <investor:eee> <objProp:HAS_FAX> <fax:555-555-9995> .
    <investor:fff> <dataProp:name> "MNO" .
    <investor:fff> <objProp:HAS_EMAIL> <email:mno-at-nobody-dot-com> .
    <investor:fff> <objProp:HAS_PHONE> <phone:555-555-1113> .
    <investor:fff> <objProp:HAS_PRIMARY_CONTACT> <pcontact:some-info-ghi> .
    <investor:fff> <objProp:HAS_FAX> <fax:555-555-9996> .

}
SELECT DISTINCT ?investor1 ?investor2 ?investor3  WHERE {
    {
        ?investor1 <dataProp:name> "XYZ" .
        ?investor1 <objProp:HAS_EMAIL> ?email1 .
        ?investor1 <objProp:HAS_PHONE> ?phone1 .
        ?investor1 <objProp:HAS_PRIMARY_CONTACT> ?pcontact1 .
        ?investor1 <objProp:HAS_FAX> ?hqfax1 .
        { SELECT ?investor2 WHERE {
        ?investor2 <objProp:HAS_EMAIL> ?email1 . 
        ?investor2 <objProp:HAS_PHONE> ?phone1 . 
        ?investor2 <objProp:HAS_PRIMARY_CONTACT> ?pcontact1 . 
        ?investor2 <objProp:HAS_FAX> ?hqfax1 . } }
        FILTER ( ?investor1 != ?investor2 )
    } UNION {
        ?investor1 <dataProp:name> "XYZ" .
        ?investor1 <objProp:HAS_EMAIL> ?email1 .
        ?investor1 <objProp:HAS_PHONE> ?phone1 .
        ?investor1 <objProp:HAS_PRIMARY_CONTACT> ?pcontact1 .
        ?investor1 <objProp:HAS_FAX> ?hqfax1 .
        { SELECT ?investor2 WHERE {
        ?investor2 <objProp:HAS_EMAIL> ?email1 . 
        ?investor2 <objProp:HAS_PHONE> ?phone1 . 
        ?investor2 <objProp:HAS_PRIMARY_CONTACT> ?pcontact1 . 
        ?investor2 <objProp:HAS_FAX> ?hqfax1 . } }
        FILTER ( ?investor1 != ?investor2 ) .
        ?investor2 <objProp:HAS_EMAIL> ?email2 . 
        ?investor2 <objProp:HAS_PHONE> ?phone2 . 
        ?investor2 <objProp:HAS_PRIMARY_CONTACT> ?pcontact2 . 
        ?investor2 <objProp:HAS_FAX> ?hqfax2 .
        { SELECT ?investor3 WHERE {
        ?investor3 <objProp:HAS_EMAIL> ?email2 . 
        ?investor3 <objProp:HAS_PHONE> ?phone2 . 
        ?investor3 <objProp:HAS_PRIMARY_CONTACT> ?pcontact2 . 
        ?investor3 <objProp:HAS_FAX> ?hqfax2 . } }
        FILTER ( ?investor2 != ?investor3 && ?investor3 != ?investor1 )
    }
   # And you would need to continue the above pattern of doing unions with increasing hops to generate the paths
}
profile pictureAWS
answered 8 months ago
  • if we have to do this for large number of hops then?

  • Do you need all intermediary nodes between each hop? Or just the leaf nodes at the end? What other query patterns are you using in this use case? What was the deciding factor to use RDF over Property Graph (as PG has better support for path finding)?

  • Updated the original post with a more clear example.

  • MATCH p= (c1: Customer {name: 'XYZ'}) - [ : HAS_EMAIL | HAS_PHONE | HAS_ADDRESS *.. 10]-(c2:Customer) WHERE c1<>c2 RETURN p I want this thing in sparql.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions