1 Answer
- Newest
- Most votes
- Most comments
1
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
}
answered 8 months ago
Relevant content
- asked 8 months ago
- AWS OFFICIALUpdated 4 years ago
- AWS OFFICIALUpdated 7 months ago
- AWS OFFICIALUpdated 4 years 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.