Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Representing (and incrementing) relationship strength in Neo4j

I would like to represent the changing strength of relationships between nodes in a Neo4j graph.

For a static graph, this is easily done by setting a "strength" property on the relationship:

  A --knows--> B
       |
     strength
       |
       3

However, for a graph that needs updating over time, there is a problem, since incrementing the value of the property can't be done atomically (via the REST interface) since a read-before-write is required. Incrementing (rather than merely updating) is necessary if the graph is being updated in response to incoming streamed data.

I would need to either ensure that only one REST client reads and writes at once (external synchronization), or stick to only the embedded API so I can use the built-in transactions. This may be workable but seems awkward.

One other solution might be to record multiple relationships, without any properties, so that the "strength" is actually the count of relationships, i.e.

A knows B
A knows B
A knows B

means a relationship of strength 3.

  • Disadvantage: only integer strengths can be recorded
  • Advantage: no read-before-write is required
  • Disadvantage: (probably) more storage required
  • Disadvantage: (probably) much slower to extract the value since multiple relationships must be extracted and counted

Has anyone tried this approach, and is it likely to run into performance issues, particularly when reading?

Is there a better way to model this?

like image 571
DNA Avatar asked Dec 12 '11 13:12

DNA


People also ask

Can relationships have properties in Neo4j?

The Neo4j Graph Data Science Library provides multiple operations to work with relationships and their properties stored in a projected graphs. Relationship properties are either added during the graph projection or when using the mutate mode of our graph algorithms.

How many nodes can a single relationship connect Neo4j?

You sometimes find cases where you need to connect more data to a relationship than can be fully captured in the properties. In other words, you want a relationship that connects more than two nodes. Mathematics allows this, with the concept of a hyperedge. This is impossible in Neo4j.

How do you add a relationship in Neo4j?

Creating Relationships We can create a relationship using the CREATE clause. We will specify relationship within the square braces “[ ]” depending on the direction of the relationship it is placed between hyphen “ - ” and arrow “ → ” as shown in the following syntax.

How many directions can a relationship have in Neo4j?

Relationships describes a connection between a source node and a target node. Relationships always has a direction (one direction).


1 Answers

Nice idea. To reduce storage and multi-reads those relationships could be aggregated to one in a batch job which runs transactionally.

Each rel could also carry an individual weight value, whose aggregated value is used as weight. It doesn't have to be integer based and could also be negative to represent decrements.

You could also write a small server-extension for updating a weight value on a single relationship transactionally. Would probably even make sense for the REST API (as addition to the "set single value" operation have a modify single value operation.

PUT http://localhost:7474/db/data/node/15/properties/mod/foo 

The body contains the delta value (1.5, -10). Another idea would be to replace the mode keyword by the actual operation.

PUT http://localhost:7474/db/data/node/15/properties/add/foo 
PUT http://localhost:7474/db/data/node/15/properties/or/foo 
PUT http://localhost:7474/db/data/node/15/properties/concat/foo 

What would "increment" mean in a non integer case?

like image 106
Michael Hunger Avatar answered Jan 01 '23 22:01

Michael Hunger