Bipartite to monopartite projection with multiple relationships

I'm new to Neo4j, and this is my first time posting. I'm trying to create a monopartite projection from a bipartite graph. I've only got two types of nodes:

  • Post nodes: These are all pieces of content, such as tweet, reddit post, news article, etc.,
  • Entity nodes: These are the entities associated with the content


My challenge is that I have a handful of different relationships. Some examples:

  • (e1:Entity) -[r:TWEETED]->(p:Post)->[r:AT_MENTIONED]->(e2:Entity)
  • (e1:Entity) -[r:TWEETED]->(p1:Post)-->[r:QUOTE_TWEETED]->(p2:Post)<-[r:TWEETED]<-(e2:Entity)
  • (e1:Entity) -[r:PUBLISHED]->(p:Post)-[r:MENTIONS]->(e2:entity)

What I'm trying to do is

  1. Change this to a monopartite graph projection that has only the entities but infers a RELATED_TO edge based on all types of relations, not just a single type of relationship and
  2. Assigns an edge weight based on the number of times two entities co-occur.

In other words, using the examples above:

Example 1:

  • Before: (e1:Entity) -[r:TWEETED]->(p:Post)->[r:AT_MENTIONED]->(e2:Entity)
  • After: (e1:Entity) -[r:RELATED_TO]-(e2:Entity)

Example 2

  • BEFORE: (e1:Entity) -[r:TWEETED]->(p1:Post)-->[r:QUOTE_TWEETED]->(p2:Post)<-[r:TWEETED]<-(e2:Entity)
  • AFTER: (e1:Entity) -[r:RELATED_TO]-(e2:Entity)

Example 3

  • Before: (e1:Entity) -[r:PUBLISHED]->(p:Post)-[r:MENTIONS]->(e2:entity)
  • After: (e1:Entity) -[r:RELATED_TO]-(e2:entity)

I can find examples online that convert only one type of relationship to a monopartite but can't seem to get anything to work for multiple relationship or relationships that have an intervening node of a different type (i.e. two post nodes between an entity node). I've done the graph data science training and couldn't find exactly what I was looking for there either.

Any advice?

If you're using GDS for monopartite projections, you can write any arbitrary Cypher query for a node projection and a rel projection. This can navigate as many steps in whatever order you like.

You've already got the right patterns, abstracting a bit you might use this as a node projection:

MATCH (e:Entity) return id(e) as id

And this as a rel projection

MATCH (a:Entity)-[]-(p:Post)-[]-(b:Entity)
RETURN id(a) as from, id(b) as to

Notice we're using blank, anonymous, un-ordered relationships -[]- meaning we don't care the rel type, we don't care which direction. We just know these things are connected with something else (a post) in the middle