Is there any possibility to create multigraph?

Hi!

Is there any possibility to create multigraph?
I mean several edges with the same types and facets but different facets values between 2 nodes.

For example:

Node A → callTo (dateCreated=1,lastSeen=2) → Node B
Node A → callTo (dateCreated=11,lastSeen=22) → Node B
Node B → callTo (dateCreated=111,lastSeen=222) → Node A

If I got it right, sure you can.

PS. But the edges need to be different.

Ok, but for example subscriber A calls to subscriber B 10 times, so i have to store 10 edges with the same type “callTo” but different facets values, startAt1…startAt10 and duration1…duration10. Is this possible somehow?

To make it “readable” I would recommend you to do a queue of calls.

{
	"set": [{
		"uid": "_:subscriberA",
		"calls": [
		  {
				"uid": "_:call_1",
				"from": "_:subscriberA",
				"to": "_:subscriberB",
				"startAt": "0",
				"duration": "0"
			},
			{
				"uid": "_:call_2",
				"from": "_:subscriberA",
				"to": "_:subscriberB",
				"startAt": "0",
				"duration": "0"
			},
			{
				"uid": "_:call_3",
				"from": "_:subscriberA",
				"to": "_:subscriberB",
				"startAt": "0",
				"duration": "0"
			},
			{
				"uid": "_:call_4",
				"from": "_:subscriberA",
				"to": "_:subscriberB",
				"startAt": "0",
				"duration": "0"
			},
			{
				"uid": "_:call_5",
				"from": "_:subscriberA",
				"to": "_:subscriberB",
				"startAt": "0",
				"duration": "0"
			},
			{
				"uid": "_:call_6",
				"from": "_:subscriberA",
				"to": "_:subscriberB",
				"startAt": "0",
				"duration": "0"
			},
			{
				"uid": "_:call_7",
				"from": "_:subscriberA",
				"to": "_:subscriberB",
				"startAt": "0",
				"duration": "0"
			},
			{
				"uid": "_:call_8",
				"from": "_:subscriberA",
				"to": "_:subscriberB",
				"startAt": "0",
				"duration": "0"
			},
			{
				"uid": "_:call_9",
				"from": "_:subscriberA",
				"to": "_:subscriberB",
				"startAt": "0",
				"duration": "0"
			},
			{
				"uid": "_:call_10",
				"from": "_:subscriberA",
				"to": "_:subscriberB",
				"startAt": "0",
				"duration": "0"
			}
		]
	}]
}

But “calls” aren’t edges in your example…
In Neo4j i can create as many edges between two nodes as i need

Can you exemplify it?

In Dgraph facets are unique between unique edges. And also, facets aren’t the first-class citizen. Thus making Facet just for trivial usage.

You can have dozens of different edges pointing in any direction. But you gonna have a giant schema tho. My example of “queue” is the best approach.

I’ve understood your approach for calls, thank you, but i have one more question

Here is my schema

		type call {
			a: string
			b: string
			startAt: dateTime
			duration: int
            status: string
		}

		type redirect {
			a: string
			b: string
			startAt: dateTime
			duration: int
            status: string
		}

		type sms {
			a: string
			b: string
			senAt: dateTime
		}

		type msisdn {
			name: string
			msisdn: string
			callTo: [call]
			redirectTo: [redirect]
			smsTo: [sms]
			correspondToImsi: [imsi]
			correspondToImei: [imei]
		}

		type imsi {
			name: string
			imsi: string
			correspondToMsisdn: [msisdn]
			correspondToImei: [imei]
		}

		type imei {
			name: string
			imei: string
			correspondToMsisdn: [msisdn]
			correspondToImsi: [imsi]
		}

		name: string @index(exact) @upsert .
		msisdn: string @index(term, trigram) @upsert @count .
		imsi: string @index(term, trigram) @upsert @count .
		imei: string @index(term, trigram) @upsert @count .
		correspondToMsisdn: [uid] @reverse @count .
		correspondToImsi: [uid] @reverse @count .
		correspondToImei: [uid] @reverse @count .
		a: string @index(term, trigram) .
		b: string @index(term, trigram) .
		callTo: [uid] @count .
		redirectTo: [uid] @count .
		smsTo: [uid] @count .

and i want to have the following facets on edges between msisdn, imsi and imei:

  1. dateCreated (dateTime) - edge creation time (won’t be changed)
  2. lastSeen (dateTime) - changes every time when system get new information about relation between msisdn, imsi or imei

I don’t understand how to create edge with two facets and update just one of them in the future

You don’t have any DateTime in your schema Types. Set it in the Type Schema (Type System) it doesn’t mean it will be automatically applied to schema Types. You need to set both.

Facets are limited, you need to capture all facets and make the change you need (Thus recreating the Facets). Changing one by one does not work. Because facets are not first-class citizens.

ok

Another question: I’ve received information about msisdn and imsi and want to save date of first appearance of their relation, but i don’t understand how to do that. Because i often receive same msisdns, imsis and imeis and use upsert procedure to create them and i have to recreate “dateCreated” in every upsert. Is there any possibility to set property only one time?

Might I suggest looking at this the other way round? A call is the starting node here surely - so a call could involve parties; each party has a redirect capability and other things.

Type Call {
    Parties [Party]
    Start datetime 
    End dateTime
    Status string
    ServiceType int 
}

Then you can simply insert a new call node with all parties involved. Party being a point in time collection of links - an entity that can then hold the device UIDs, subscriber UIDs, your redirect data and any other metadata available at the time (geolocation, cell ID etc) too.

This also allows you to resolve multi-party calls and other services too. So a call might actually represent an “event” - call, message or other thing - hence suggesting a servicetype field.

Why not support multiple edges between two nodes? Will the relationship between two nodes be directly represented by edges in the future?

It does. You can have as many edges as you want, but they need to have different names. Atomically speaking, an edge/predicate is a unique thing (“key”) in the DB.

That is the reason, two predicates/edges cannot occupy the same space.

This happens when the relationship is 1:1 (One to one), however, as exemplified there in the old comments. You can use an intermediate queue of nodes. That way you can create a 1:Many relationships with additional information needed.

I don’t see a logical reason for this. Please, open a new ticket with examples of what you wanna do. With real use cases. That way we can try to elaborate a solution or support it, if so. But we need to understand why this is useful.

1 Like

My scenario is: a bank card a makes multiple transfers to bank card B. according to the model in the diagram, I only need to directly create multiple edges between the two bank cards a and B (one side for each transaction and the type of edge is the same). According to your solution, I need to create a queue to save the transaction information, and store the information of B card related to the transaction in the queue Even many objects were processed in this way before, but I found it very troublesome to query, especially in reverse query. Now I create a transaction object t for a transaction, and translate it through two attributes in t_ source, translate_ Target to save the information of cards a and B. I want to know. Is there any other way? Although the original two nodes in the development process can increase the amount of work in the development process.

IMO, this is the right way. The transaction is an important entity to be a full “type” or node, with links going out to cards participating in the transaction.

How do you consider solving the problem of multiple edges of the same type between two nodes when designing a database? In addition to using queues or abstracting a type node object separately, is there any other way that is simpler than this? In fact, my original intention is that transactions are regarded as edges, and these transaction information should be placed on the edges? This makes it easier to describe a very complex relationship.

IMO, anything that can serve as a class, and can have several real world instances, such as “Transaction” is a good candidate to be modeled as a type, and not as an edge.

As a good industry example, please review this schema for an order. An Order can have several scalar properties as well as relations to other classes, like customer (type Organization or Person).

Adding complex information through a single edge would be tricky and maybe confusing for some. I do not see how it would be beneficial for the user. In addition, it would be necessary to change fundamental things in the Dgraph core, perhaps create a new type of edge just to accommodate this characteristic - And for that to happen, it has to have a certain degree of utility and popularity. An entity queue is much more efficient and information compliant(in the concept of Knowledge Graph).

About your difficulty in dealing with queues of entities, please open a new topic demonstrating what you are doing and how bad it is.

BTW It is not good to add comments on old topics as it will not help who posted(if it helps, please do it). To prevent other people from receiving unnecessary emails, it is recommended that you open a new topic and if necessary referenciate this topic as context.

Cheers.

1 Like