DB graph gets next best recommended node in Neo4j cypher

I have a chart using NEO4j and currently trying to create a simple recommendation system that is better than text based search.

Nodes are created, such as: Album, People, Type, Chart

Relationships are created, such as:

People - [:role] -> Album where roles: Artist, Producer, Composer

Album-[:is_a_type_of]->Type (type mainly Pop, Rock, Disco ...)

People -[:POPULAR_ON]->Chart (A chart is a billboard they might be)

People -[:SIMILAR_TO]->People (specified similarity connection)

I wrote the following cypher:

  MATCH (a:Album { id: { id } })-[:is_a_type_of]->(t)<-[:is_a_type_of]-(recommend) WITH recommend, t, a MATCH (recommend)<-[:ARTIST_OF]-(p) OPTIONAL MATCH (p)-[:POPULAR_ON]->() RETURN recommend, count(DISTINCT t) AS type ORDER BY type DESC LIMIT 25; 

It works, however, it is easy to repeat if it has only one type of music associated with it, so it has the same neighbors.

Is there any way to say:

  • Find me the next best album that has the most similar relationship with the original album.
  • Any recommendation for a tiebreak scenario? Now this is an order by type (so if an album has more than one type of music, it is valued more, but if each has the same number, it no longer matters)
  • -I made a link [: SIMILAR_TO] to provide priority to consider this relationship important, but I did not have a working cypher with it.
  • -Changed for [: Popular_On] (Maybe Drop this relationship?)
+5
source share
1 answer

You can use 4 configurations and arrange albums according to a higher value in that order. Save the configuration from 0 to 1 (e.g. 0.6)

 a. People Popular on Chart and People are similar b. People Popular on Chart and People are Not similar c. People Not Popular on Chart and People are similar d. People Not Popular on Chart and People are Not similar 

Calculate and summarize these 4 values ​​with each album. The higher the value, the higher the recommended album.

I temporarily made config as a = 1, b = 0.8, c = 0.6, d = 0.4. And suggested that some relationships are present, which suggests that some people love the album. If you are making logic based on Chart only, use only a and b.

 MATCH (me:People) where id(me) = 123 MATCH (a:Album { id: 456 })-[:is_a_type_of]->(t:Type)<-[:is_a_type_of]-(recommend) OPTIONAL MATCH (recommend)<-[:ARTIST_OF]-(a:People)-[:POPULAR_ON]->(:Chart) WHERE exists((me)-[:SIMILAR_TO]->(a)) OPTIONAL MATCH (recommend)<-[:ARTIST_OF]-(b:People)-[:POPULAR_ON]->(:Chart) WHERE NOT exists((me)-[:SIMILAR_TO]->(b)) OPTIONAL MATCH (recommend)<-[:LIKES]-(c:People) WHERE exists((me)-[:SIMILAR_TO]->(a)) OPTIONAL MATCH (recommend)<-[:LIKES]-(d:People) WHERE NOT exists((me)-[:SIMILAR_TO]->(a)) RETURN recommend, (count(a)*1 + count(b)*0.8 + count(c)* 0.6+count(d)*0.4) as rec_order ORDER BY rec_order DESC LIMIT 10; 
+1
source

Source: https://habr.com/ru/post/1232843/


All Articles