如果我們知道用戶(hù)看過(guò)了哪些電影,我們可以使用此信息來(lái)推薦類(lèi)似的電影:
// Content recommendation by overlapping genres
MATCH (u:User {name: "Angelica Rodriguez"})-[r:RATED]->(m:Movie),
(m)-[:IN_GENRE]->(g:Genre)<-[:IN_GENRE]-(rec:Movie) WHERE NOT EXISTS( (u)-[:RATED]->(rec) )
WITH rec, [g.name, COUNT(*)] AS scores
RETURN rec.title AS recommendation, rec.year AS year,
COLLECT(scores) AS scoreComponents,
REDUCE (s=0,x in COLLECT(scores) | s+x[1]) AS score
ORDER BY score DESC LIMIT 10
返回結(jié)果如下:

分析:
確定用戶(hù)Angelica
找出用戶(hù)評(píng)過(guò)分的電影m
把被評(píng)分的電影的流派找出來(lái)(g:Genre)
通過(guò)流派g再返回去搜索屬于該流派的電影 (rec:Movie),并且是Angelica 沒(méi)有評(píng)過(guò)分的那部分電影
返回電影,根據(jù)流派名稱(chēng)數(shù)量來(lái)打分 ——?[g.name, COUNT(*)] AS scores
把Scores 列表中的數(shù)據(jù)列出來(lái) ——?COLLECT(scores) AS scoreComponents,
從Scores 列表中,把名稱(chēng)數(shù)量提取出來(lái)相加,作為得分 ——?REDUCE (s=0,x in COLLECT(scores) | s+x[1]) AS score
按得分高低排序
這里運(yùn)用到了幾個(gè)函數(shù)和表達(dá)式:
1.?[‘a(chǎn)’, ‘b’, ‘c’] AS list
? ? Literal lists are declared in square brackets.
2.?collect(n.property)
? ? List from the values, ignores?null.
3.?reduce(s = “”, x IN list | s + x.prop)
? ? Evaluate expression for each element in the list, accumulate the results.
備注:
[g.name, COUNT(*)] AS scores
這句話想了很久什么意思。因?yàn)樽罱K是要返回rec 記錄,假設(shè)我們已經(jīng)找到了rec,那么rec 記錄中的每一條,它的流派是清晰的。那么它的流派,在 m 中出現(xiàn)過(guò)多少次,就是 [g.name, count(*)] 的結(jié)果。

Neo4j 做推薦 (1)—— 基礎(chǔ)數(shù)據(jù)
Neo4j 做推薦 (2)—— 基于內(nèi)容的過(guò)濾
Neo4j 做推薦 (3)—— 協(xié)同過(guò)濾
Neo4j 做推薦 (4)—— 基于內(nèi)容的過(guò)濾(續(xù))
Neo4j 做推薦 (5)—— 基于類(lèi)型的個(gè)性化建議
Neo4j 做推薦 (6)—— 加權(quán)內(nèi)容算法
Neo4j 做推薦 (7)—— 基于內(nèi)容的相似度量標(biāo)準(zhǔn)
Neo4j 做推薦 (8)—— 協(xié)同過(guò)濾(利用電影評(píng)級(jí))
Neo4j 做推薦 (9)—— 協(xié)同過(guò)濾(人群的智慧)
Neo4j 做推薦 (10)—— 協(xié)同過(guò)濾(皮爾遜相似性)