我有一组文件,每组都属于一个或几个小组。
人们可以推荐这些文件
我需要为每个组提供在收到建议数量方面位置为1到N的文档,这意味着当这是一个中间结果并且N = 3时
Document Recommendations
a 7
b 4
c 4
d 3
它将返回a,b和c
有了这个:
Document Recommendations
a 6
b 5
c 4
d 4
它将返回a,b,c和d
并使用此
有了这个:
Document Recommendations
a 6
b 4
c 4
d 4
e 3
它将返回a,b,c和d
我如何在Cypher中做这种事情?我已经做到了这一点(计划将一个链接放到控制台但它似乎不起作用)
//Groups
create (gr1:Group {name:"First group"})
create (gr2:Group {name:"Second group"})
//Persons
create (p1:Person {name:"Jan"})
create (p2:Person {name:"Marie"})
create (p3:Person {name:"Willem"})
create (p4:Person {name:"Simone"})
create (p5:Person {name:"Henk"})
create (p6:Person {name:"Ilse"})
create (p7:Person {name:"Tom"})
create (p8:Person {name:"Detlef"})
//Content
create (ci1:Contentitem { title: "Sometitle 1"})
create (ci2:Contentitem { title: "Sometitle 2"})
create (ci3:Contentitem { title: "Sometitle 3"})
create (ci4:Contentitem { title: "Sometitle 4"})
create (ci5:Contentitem { title: "Sometitle 5"})
create (ci6:Contentitem { title: "Sometitle 6"})
create (ci7:Contentitem { title: "Sometitle 7"})
create (ci8:Contentitem { title: "Sometitle 8"})
create (ci9:Contentitem { title: "Sometitle 9"})
create (ci10:Contentitem { title: "Sometitle 10"})
//Recommendations
create (ci1)-[:IsRecommendedBy]->(p4)
create (ci8)-[:IsRecommendedBy]->(p8)
create (ci1)-[:IsRecommendedBy]->(p1)
create (ci8)-[:IsRecommendedBy]->(p7)
create (ci5)-[:IsRecommendedBy]->(p6)
create (ci1)-[:IsRecommendedBy]->(p3)
create (ci8)-[:IsRecommendedBy]->(p3)
create (ci5)-[:IsRecommendedBy]->(p4)
create (ci8)-[:IsRecommendedBy]->(p5)
create (ci5)-[:IsRecommendedBy]->(p2)
create (ci5)-[:IsRecommendedBy]->(p1)
create (ci5)-[:IsRecommendedBy]->(p8)
create (ci2)-[:IsRecommendedBy]->(p1)
create (ci2)-[:IsRecommendedBy]->(p3)
create (ci2)-[:IsRecommendedBy]->(p7)
create (ci10)-[:IsRecommendedBy]->(p8)
create (ci3)-[:IsRecommendedBy]->(p4)
create (ci10)-[:IsRecommendedBy]->(p5)
create (ci3)-[:IsRecommendedBy]->(p1)
create (ci4)-[:IsRecommendedBy]->(p5)
create (ci4)-[:IsRecommendedBy]->(p8)
create (ci6)-[:IsRecommendedBy]->(p5)
create (ci9)-[:IsRecommendedBy]->(p1)
create (ci9)-[:IsRecommendedBy]->(p2)
create (ci6)-[:IsRecommendedBy]->(p6)
create (ci6)-[:IsRecommendedBy]->(p8)
//Group membership
create (ci1)-[:BelongsToGroup]->(gr1)
create (ci1)-[:BelongsToGroup]->(gr2)
create (ci2)-[:BelongsToGroup]->(gr1)
create (ci3)-[:BelongsToGroup]->(gr1)
create (ci4)-[:BelongsToGroup]->(gr1)
create (ci4)-[:BelongsToGroup]->(gr2)
create (ci5)-[:BelongsToGroup]->(gr1)
create (ci6)-[:BelongsToGroup]->(gr1)
create (ci7)-[:BelongsToGroup]->(gr1)
create (ci8)-[:BelongsToGroup]->(gr1)
create (ci8)-[:BelongsToGroup]->(gr2)
create (ci10)-[:BelongsToGroup]->(gr1)
create (ci10)-[:BelongsToGroup]->(gr2)
;
和查询
match (gr)<-[:BelongsToGroup]-(ci:Contentitem)-[:IsRecommendedBy]->(p:Person)
return gr.name,ci.title,count(p) as Recommendations
order by gr.name, Recommendations desc
返回
gr.name ci.title Recommendations
----------------------------------------------------
First group Sometitle 5 5
First group Sometitle 8 4
First group Sometitle 1 3
First group Sometitle 6 3
First group Sometitle 2 3
First group Sometitle 4 2
First group Sometitle 3 2
First group Sometitle 10 2
Second group Sometitle 8 4
Second group Sometitle 1 3
Second group Sometitle 10 2
Second group Sometitle 4 2
N = 3,最终结果应为
gr.name ci.title Recommendations
----------------------------------------------------
First group Sometitle 5 5
First group Sometitle 8 4
First group Sometitle 1 3
First group Sometitle 6 3
First group Sometitle 2 3
Second group Sometitle 8 4
Second group Sometitle 1 3
Second group Sometitle 10 2
Second group Sometitle 4 2
N = 2,最终结果为
gr.name ci.title Recommendations
----------------------------------------------------
First group Sometitle 5 5
First group Sometitle 8 4
Second group Sometitle 8 4
Second group Sometitle 1 3
在以下规则中重要的是,在位置&lt; = N处开始的建议数量最少的组不会在任意位置被切断,而是完全包含在内。所以,当我们像这样截止前的情况时
gr.name ci.title Recommendations
----------------------------------------------------
First group Sometitle 5 5
First group Sometitle 8 4
First group Sometitle 1 4
First group Sometitle 6 3
First group Sometitle 2 3
First group Sometitle 4 2
First group Sometitle 3 2
First group Sometitle 10 2
Second group Sometitle 8 4
Second group Sometitle 1 4
Second group Sometitle 10 2
Second group Sometitle 4 2
Second group Sometitle 7 1
N = 3的最终结果是:
gr.name ci.title Recommendations
----------------------------------------------------
First group Sometitle 5 5
First group Sometitle 8 4
First group Sometitle 1 4
Second group Sometitle 8 4
Second group Sometitle 1 4
Second group Sometitle 10 2
Second group Sometitle 4 2
并且对于N = 2
gr.name ci.title Recommendations
----------------------------------------------------
First group Sometitle 5 5
First group Sometitle 8 4
First group Sometitle 1 4
Second group Sometitle 8 4
Second group Sometitle 1 4
答案 0 :(得分:3)
我认为没有一种干净的方法可以做到你想要的,但这是我最好的尝试。在找出截止值后,它需要第二场比赛。
这样的事情:
match (gr)<-[:BelongsToGroup]-(ci:Contentitem)-[:IsRecommendedBy]->(p:Person)
with gr, ci, count(p) as recommendations
order by recommendations desc
with gr, collect(recommendations) as cutoffs
// coalesce here to avoid null problems if you don't have N=3 distinct recommendations
with gr, coalesce(cutoffs[2], cutoffs[1], cutoffs[0]) as cutoff
match (gr)<-[:BelongsToGroup]-(ci:Contentitem)-[:IsRecommendedBy]->(p:Person)
with gr, ci, count(p) as recommendations, cutoff
where recommendations >= cutoff
return gr.name, ci.title, recommendations, cutoff
order by gr.name, recommendations desc;
给出:
+------------------------------------------------------------+
| gr.name | ci.title | recommendations | cutoff |
+------------------------------------------------------------+
| "First group" | "Sometitle 5" | 5 | 3 |
| "First group" | "Sometitle 8" | 4 | 3 |
| "First group" | "Sometitle 1" | 3 | 3 |
| "First group" | "Sometitle 6" | 3 | 3 |
| "First group" | "Sometitle 2" | 3 | 3 |
| "Second group" | "Sometitle 8" | 4 | 2 |
| "Second group" | "Sometitle 1" | 3 | 2 |
| "Second group" | "Sometitle 4" | 2 | 2 |
| "Second group" | "Sometitle 10" | 2 | 2 |
+------------------------------------------------------------+
9 rows
更新:我想到你可能想要传递N
而不是像coarthce一样编码。在这种情况下,您可以这样做:
with gr, reduce(acc=cutoffs[0], x in range(0, {N}-1)| coalesce(cutoffs[x], acc)) as cutoff
这将通过0到N-1的范围,而不需要像第一个解决方案那样硬编码。
答案 1 :(得分:2)
你已经得到了一个很好的答案(+1),但我很好奇是否可以在没有第二场比赛的情况下完成。这是我想出来的
MATCH (gr)<-[:BelongsToGroup]-(ci:Contentitem)-[r:IsRecommendedBy]->() // I dropped (p:Person) since it's not really relevant, and counted the [:IsRecommendedBy] instead
WITH gr, [ci, count(r)] AS document
ORDER BY document[1] desc
WITH gr, collect(document) as documents, collect(document[1]) as recommendations
WITH gr, documents, recommendations,
CASE WHEN length(recommendations) >= {n} THEN {n}-1 ELSE length(recommendations)-1 END as ix
RETURN gr.name AS group,[doc IN documents
WHERE doc[1]>= recommendations[ix]| [(doc[0]).title, doc[1]]] AS documents
我不知道这是否一定更好,但它有所不同,只有一个匹配CASE WHEN
而不是REDUCE/COALESCE
以避免索引问题,并且每个组返回一行有序收集[文件,推荐]对;也许那里有一些可用的东西。