cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Can I add multiple relationships between two nodes to store different data?

geronimo4j
Graph Buddy

Hi my end goal is to have users (User nodes) able to track (Playlist nodes) which movies (Movie nodes) they've seen and also when they saw them, so it's possible that a user has seen Dune 17 times and each of those 17 times would have a date and maybe some other metadata to make them unique.

Is it possible to track these 17 times using relationships and storing that date/extra metadata somehow?

Like would I be able to say User - [HAS_PLAYLIST] - Playlist - [HAS_MOVIE [{ date: 11/08/2021}, {date: 10/23/2021}] - Dune

And if so, how might you approach that? I'm using graphQL! Appreciate any help here

I have node types that, roughly, look like this:

type User {
    id: ID! @id(autogenerate: true),
    name: String,
    ...
    user_playlists: [Playlist] @relationship(type: "HAS_PLAYLIST", direction: OUT),
}

type Playlist {
    id: ID! @id(autogenerate: true),
    name: String!,
    movies: [Movie] @relationship(type: "HAS_MOVIE", direction: IN)
}

type Movie {
    id: ID! @id(autogenerate: true),
    name: String!,
}

Thank you in advance!

5 REPLIES 5

Hi,

If I understand correctly you need to track:

  • User playlist
  • Movies watched
  • Movie Soundtrack

You probably shouldn't do:

Playlist - [HAS_MOVIE [{ date: 11/08/2021}, {date: 10/23/2021}] - Dune

because you don't want the rels between Playlist and Movies to contain user specific information.

You can store the date that a user watched a movie on a relationship like:

(:User)-[:WATCHED_MOVIE { watch_date: [11/08/2021]}]->(:Movie)

And in your QraphQL schema you would add:
user Type def:

user_watched_movie: [Movie] @relationship(type: "WATCHED_MOVIE", properties: "WatchedMovie", direction: OUT)

and

interface WatchedMovie @relationshipProperties {
    watch_date: [DateTime!]
}

Where watch_date is an array of dates that you can append too.

I hope that helps.

Hi @SamChalvet very cool and thank you very much! And Happy Birthday!

I was thinking I can map the playlists to Movies, even without the User data I think for now it is OK that playlists are specific to users, so the user info is implied by the Playlist <-> Movie relationshp.

In my Type definition for Movie I have:

movie_added: [Thing] @relationship(type: "ADDED_EVENT", properties: "AddedEvent", direction: OUT),

I'm messing around to see what my options are for adding these relationships, so I can add new dates. It seems I will always need to grab and send the list of DateTimes, is that correct? I'm trying to see if there's any way for me to just update to append new dates, without having to send the already-stored dates.

I'm trying currently with an updatePlaylists, and then calling update with it. This is a mutation I was trying below, what do you think, is this what I should be doing to add new dates and is there any way to append to this list without having to send the already-stored dates?

mutation UPDATE_PLAYLIST{
  updatePlaylists( where: { id: "1cb54acd-b94d-4525-8a02-cabd7ace1fce"}, 
    update: {
      thing_added: {
        connect: {
          where: {
            node: {
              id: "13e989b1-e5e9-4ba2-99ea-24890e3b366f"
            }
          }
          edge: {
            added_event: ["10/31/2021", "10/30/2021"]
          }
        }
      }
    }){
    playlists {
      id
    	name
     movie_addedConnection{
        edges{
          added_event
        }
      }
    }
  } 
}

Thanks again!! Really appreciate your help!

Hi Dan,

Check here on appending an item to an array in graphQL, in cypher you would simply do n.my_array = n.my_array + new_date.

However can you explain a bit more what you trying to achieve? Are you saving each instance anyone listens to a play list?

Depending on the information you need to store (and retrieve later), you could just save the last 10 dates a playlist was played, and a counter for the total number of times it was played.

If you need to save every instance that it was played it would probably be best to save the data on a node, with a date property. If you are not interested in creating a rel between user and the event, you could still save the user_name on the event node.

Your graph schema will be heavily determined by what exactly you want to do. And the great thing about Neo4j is that as time goes by, and your business needs change, it is very easy to update/adapt your graph schema to meet the new requirements.

Hi @SamChalvet thanks again and appreciate that link, that's helpful.

Looks like with Neo4j maybe we don't append to relationships in the same way. I'm trying with the above connect and adding the edge and also tried:

 updatePlaylists( where: { id: "1cb54acd-b94d-4525-8a02-cabd7ace1fce"}, 
    update: {
      things: {
        	where: {
            node: {
              id: "21732715-2aa2-4c4b-9c45-ea4985f2113c"
            }
          }
        update: {
          edge: {
           date_added: ["10/06/2021"]
          }
        }
      }
    })

But it just replaces the existing values instead of appending. So I think I can explore something else, rather than keep the dates in the relationship properties (although that does seem like the best way, just can't get it to work).

Basically I'd like users to be able to create lists and then add movies to that list, and be able to track dates for that specific movie on that specific list.

So to do that originally I was just thinking I would keep track of each date on the relationship between the Movie and the Playlist, since for now lists can only be owned/created by the same person so the user data is implied by whichever User node were connected to that Playlist. So it's a diary for each time you've watched a film, basically, so you can track over time.

Thinking through what you suggested I guess I could add Date nodes, I guess that sit between Playlists and Movies?

Hi Dan,

I hope you were able to take some time off
Here is what I would suggest. It tracks the info you need, with the ability to later on track who watched a movie, and when.
I wouldn't connect the WatchDate node to the Playlist because while they are created and owned by the same person, I'm assuming that different Playlists owned by the same user could have the same Movie on them.

This does not solve the issue if you need to track that a user played a movie from a certain playlist. If that is the case then I guess I would have the node sit between Playlist and Movie.

Let me know if this makes sense to you.