Cypher:使用公共节点关系链接为医生推荐文章

时间:2019-03-01 10:07:47

标签: neo4j cypher

用例

我的应用程序应根据用户(医生)的个人资料和用户操作向其推送文章。在以下示例中,请考虑(另请参见下图):

  • 两位医生(一位是专业:医生,专长:肿瘤学,另一位是医生,专长:未知)
  • 已将一篇文章手动链接到Profession:Doctor,Specialty:Oncology和Keyword:Knee手术(即向与该个人资料匹配的用户显示此文章。)

前端将用户ID发送到后端,后端需要用n条与用户个人资料匹配的文章作为响应。

enter image description here

问题

在给定用户个人资料的情况下,什么Neo4j密码查询基本上可以转换为MATCH (a:Article)...。或者说不同的查找(a:Article)[....],它与用户具有的Profession,Keyword和Specialty节点具有相似的关系

密码查询应该是什么样的形状?

1 个答案:

答案 0 :(得分:1)

TL; DR

这是一个开始:

MATCH p=(u:User {id: $theID})-[:r]->()<-[:m]-(a:Article)
WITH a, COUNT(p) as rank
RETURN a.name, rank
ORDER BY rank DESC
LIMIT $n

这里的想法是只计算从用户到每篇文章的所有路径,然后将其用作排名。路径越多,即专业和关键字越常见,排名越高。

长版...更多数据,“等级”验证

我很确定您的查询将随着图形数据库的增长和您调整架构而发展,也就是说,您可能会有更多的关系类型和连接。

要获取更多数据,我制作了一些假医生,文章等。我敢肯定,有更好的方法可以做到这一点。

MERGE (p:Profession {name: "Doctor"})
WITH p, ["Fred","Wilma","Pebbles","Dino","Barney","Betty","Bamm-bamm", "Hoppy"] as doctors
UNWIND doctors as doc
MERGE (d:User {name: doc})-[:R]->(p);

WITH ["Oncology", "Pathology","Pediatrics","ENT","Radiology","Dermatology"] as specialties
UNWIND specialties as spec
MERGE (:Specialty {name: spec});

MATCH (d:User)
WITH d, ["Oncology", "Pathology","Pediatrics","ENT","Radiology","Dermatology"] as specialties
UNWIND apoc.coll.randomItems(specialties, toInteger(apoc.text.random(1,"00111223"))) as docspec
MATCH (spec:Specialty {name: docspec})
MERGE (d)-[:R]->(spec);

WITH ["Knee Surgery","Ear Injury","Throat Cultures","Radial fractures", "Arm rash", "Mole color"] as keywords
UNWIND keywords as key
MERGE (:Keyword {name: key});

MATCH (d:User)
WITH d, ["Knee Surgery","Ear Injury","Throat Cultures","Radial fractures", "Arm rash", "Mole color"] as keywords
UNWIND apoc.coll.randomItems(keywords, toInteger(apoc.text.random(1,"01112233"))) as docword
MATCH (key:Keyword {name: docword})
MERGE (d)-[:R]->(key);

MATCH (p:Profession {name: "Doctor"})
WITH p, ["Useful article","Cool article","Awesome article","Research article","Nifty article","Health article"] as articles
UNWIND articles as art
MERGE (:Article {name: art})-[:M]->(p);

MATCH (art:Article)
WITH art, ["Oncology", "Pathology","Pediatrics","ENT","Radiology","Dermatology"] as specialties
UNWIND apoc.coll.randomItems(specialties, toInteger(apoc.text.random(1,"111223"))) as artspec
MATCH (spec:Specialty {name: artspec})
MERGE (art)-[:M]->(spec);

MATCH (art:Article)
WITH art, ["Knee Surgery","Ear Injury","Throat Cultures","Radial fractures", "Arm rash", "Mole color"] as keywords
UNWIND apoc.coll.randomItems(keywords, toInteger(apoc.text.random(1,"1112233"))) as artword
MATCH (key:Keyword {name: artword})
MERGE (art)-[:M]->(key);

这是交织在一起的烂摊子。

enter image description here

现在只看一位“医生”:

MATCH p=(u:User {name: "Barney"})-[:R]->()<-[:M]-(a:Article)
RETURN p

...您可以看到他所连接的所有文章。

enter image description here

所以,让我们按与医生的联系数对其进行排名。

MATCH p=(u:User {name: "Barney"})-[:R]->()<-[:M]-(a:Article)
WITH a, COUNT(p) as rank
RETURN a.name, rank
ORDER BY rank DESC

enter image description here

博士Barney可能会对“漂亮的文章”感兴趣。

有很多排名方法,这只是一种简单的方法。