How to save multi edges between same nodes with different facets values?

How to save multi edges between same nodes with different facets values?

for example, Alice has been to the U.S. twice, and I want to keep track start_time and end_time of her two trips to the U.S.

{
  set{
    _:alice <name> "Alice" .
    _:alice <travel>  _:USA (start_time=2001-01-02T15:04:05, end_time=2002-01-02T15:04:05).
    _:alice <travel>  _:USA (start_time=2006-01-02T15:04:05, end_time=2007-01-02T15:04:05).
    _:USA <name> "united states of america" .
    _:bob <name> "Bob" .
    _:bob <travel>  _:USA (start_time=2016).
  }
}

_:alice <travel> _:USA (start_time=2006-01-02T15:04:05, end_time=2007-01-02T15:04:05).
Instead of creating a new edge between _:alice and _:USA this line just update the old one.

Here is the query and result:

{
  q(func: eq(<name>,"Alice")){
    uid
    name
    <travel> @facets{
   		 <name>
  	}
  }
}

That’s not possible. You can’t have multiple edges with the same name. What you can do is create an intermediate Queue of nodes. That way you don’t even have to use facets. Because you can add the information on the intermediate node itself.

2 Likes

Hi Michel,

I have a couple of questions regarding the same:

  1. Why this limitation was added? Is there any specific reason for the same?
  2. For example: Considering large amount of transaction data, billions of intermediate nodes will be created.
    i) Is it the optimised data model?
    ii) How will be the performance of the queries after adding billions of intermediate nodes?

Thanks & Regards,
Vinayak

An Edge is a fundamental piece in a Graph DB. They can’t have the same name, as the Edge itself(the value edge and the relational edge) is the atomic part of the system. There’s no logical way to a node have two edges with the same name in Dgraph’s design.

About the facet, well the Facet is recorded along with the edge(mean, the same “slot” in a way of saying it). As the edge can’t be repeated, you can’t have multiple Facets for the same edge and so on.

That’s not a “Limitation”, that’s a product of Dgraph’s design focussed in data distribution. Also, I don’t record any DB that offer this. If they do, hardly they would be using the same design as Dgraph. And just like Isaac Newton would say, two objects cannot occupy the same space at the same time.

e.g:

You can’t have two edges called “Friends” and each one of them points to different people. You should make a logical separation. e.g: <Close.Friends> and <NotSoClose.Friends> in an exaggerated way of explaining it.

Is the only model. And for me, it is totally fine in terms of perf.

As the same as adding billions of repeated edges in the same object. That object would crazily “fat” with billions of edges.

PS. Now you have Facets on list https://dgraph.io/docs/mutations/facets-in-list-type-with-rdf/#sidebar which is “similar” to what was asked.
Also see https://dgraph.io/docs/mutations/json-mutation-format/#facets-in-list-type-with-json

Cheers.

1 Like

This is a serious limitation for any practical application of Graph to real life data modeling.

Ex: Car has 4 tires, how do I mention which location of tire I am servicing?
Another one, I have Part and I have 4 screws to fit, how do we model to represent which locations to fit in?

I don’t understand the mentioned limitation. Can you elaborate better? Give for example how you did do it with some other DB.

I mean, a car has 4 tires so they can be different nodes:

(car)--[has_tires]->(tire{Id:1,loc:fr})
     |-[has_tires]->(tire{Id:2,loc,fl})
     |-[has_tires]->(tire{Id:3,loc,rr})
     \-[has_tires]->(tire{Id:4,loc,rl})

The more appropriate issue is temporal relationships that may be valid for multiple unique ranges - then @MichelDiz had a suggestion of just putting a node in the middle of a relation to assign a different value to:

(Person)--[is_president]->(p1{year:2020})-[president_of]->(Location)
        \-[is_president]->(p2{year:2021})-[president_of]-^
1 Like

I think this is a modeling problem, not a Dgraph problem.

I’m assuming you have something like this:

_:car <parts> _:tire .

and you want to do something like:

_:car <parts> _:tire (position="Left-Front" ) .
_:car <parts> _:tire (location="Right-Front") .
_:car <parts> _:tire (location="Left-Rear") .
_:car <parts> _:tire (location="Right-Rear") .

which is not possible because the last triple would overwrite the first being that it is the same edge.

I think the original intent is that it is the same part number, so you want it to be a singular part using the part number for the xid of the node.

And herein is where I realized what you were trying to do.

This is why NASA and other engineering teams use property graphs. It can easily be seen what all a single change to a single part affects to the whole. If there is a failure of a bolt it can be found quickly every place that uses that same bolt. So as you stated:

Which I think if you step back you see that you answered the question yourself . Model the location as a node, then your parts don’t have to be duplicate nodes.

type Part {
  partNumber
  connectsTo
}
type Connection {
  reference
}
partNumber: string @index(hash) @xid .
connectsTo: [uid] @reverse .
reference: string @index(hash)

And data could be:

_:rimX <partNumber> "RIM" .
_:boltY <partNumber> "BOLT" .
_:location_1 <reference> "Location 1" .
_:location_2 <reference> "Location 2" .
_:location_3 <reference> "Location 3" .
_:location_4 <reference> "Location 4" .
_:rimX <connectsTo> _:location_1 .
_:rimX <connectsTo> _:location_2 .
_:rimX <connectsTo> _:location_3 .
_:rimX <connectsTo> _:location_4 .
_:boltY <connectsTo> _:location_1 .
_:boltY <connectsTo> _:location_2 .
_:boltY <connectsTo> _:location_3 .
_:boltY <connectsTo> _:location_4 .

Using this model you could query to get all parts that are connected with said bolt:

query {
  var(func: eq(partNumber,"BOLT")) {
    connectsTo {
      linkedParts as ~connectsTo
    }
  }
  affectedParts(func: uid(linkedParts)) {
    uid
    partNumber
  }
}

And you can still query how many of the same part are needed when replacing a connecting part.

3 Likes

@iluminae @amaster507 lol you guys are awesome! thanks for jumping in in.

BTW

these blank nodes are repeated

1 Like

fixed my copy/paste error, thanks!

2 Likes