教程:构建 Cypher 推荐引擎
图无处不在。通过跟踪人和电影之间的有意义的关系,您可以确定演员一起工作的次数、演员彼此合作的频率以及他们在图中共同出演的电影。这是一种根据用户之前喜欢的电影和他们最喜欢的演员向用户推荐电影的方法。我们将逐步引导您完成开始使用 AuraDB 和 Cypher® 以解决现实世界问题所需的一切。
设置
创建 AuraDB 帐户后,单击“创建数据库”并选择一个免费数据库

然后,填写名称,并为您的数据库选择一个云区域,然后单击“创建数据库”。确保选中“使用电影数据集了解图”,这样您就可以从一个数据集开始。

AuraDB 会在设置新实例时提示您输入新实例的密码。**请务必保存密码以备后续步骤使用**。
数据库运行后,打开浏览器,如下所示。

现在您已进入 Neo4j 浏览器。使用您的用户名和密码(您上面捕获的密码)登录。您会立即注意到左侧有一个指南,您可以点击它开始进行一些实验性查询。您可以通过单击右侧的“播放”按钮,自动将您看到的任何查询放入查询执行框并在屏幕右侧运行。

第一个查询只是显示数据库中的一些电影,以证明其中确实有一些内容。恭喜,您在新的数据库中有一些数据,我们准备开始了。
下一节将向您展示如何编写一些查询来探索您刚刚创建的数据。
基本查询
在我们开始推荐内容之前,我们需要找出数据中哪些内容有趣,以了解我们可以和想要推荐哪些内容。首先,让我们运行如下查询以查找像汤姆·汉克斯这样的单个演员。
MATCH (tom:Person {name: 'Tom Hanks'})
RETURN tom

现在我们找到了我们感兴趣的演员,我们可以通过从汤姆·汉克斯
节点开始并沿着ACTED_IN
关系进行遍历来检索他所有的电影。您的结果应该看起来像一个图。
MATCH (tom:Person {name: 'Tom Hanks'})-[r:ACTED_IN]->(movie:Movie)
RETURN tom, r, movie

当然,汤姆在电影中有和他一起演出的同事。查找汤姆的同事的语句如下所示
MATCH (tom:Person {name: 'Tom Hanks'})-[:ACTED_IN]->(:Movie)<-[:ACTED_IN]-(coActor:Person)
RETURN coActor.name

使用协同过滤进行推荐
我们现在可以将上面的同事查询转换为推荐查询,方法是再沿着这些关系再走一步,找到“同事的同事”,即汤姆网络中的二级演员。这将向我们展示汤姆可能尚未合作的所有演员,我们可以指定一个条件来确保他尚未直接与那个人合作。
MATCH (tom:Person {name: 'Tom Hanks'})-[:ACTED_IN]->(movie1:Movie)<-[:ACTED_IN]-(coActor:Person)-[:ACTED_IN]->(movie2:Movie)<-[:ACTED_IN]-(coCoActor:Person)
WHERE tom <> coCoActor
AND NOT (tom)-[:ACTED_IN]->(:Movie)<-[:ACTED_IN]-(coCoActor)
RETURN coCoActor.name

您可能注意到,有一些名称多次出现。这是因为从汤姆·汉克斯到这些演员有多条路径可以遵循。
要查看汤姆的网络中最常出现的同事的同事,我们可以考虑出现的频率,方法是计算汤姆·汉克斯和每个coCoActor之间的路径数量,并按从高到低的顺序排序。
MATCH (tom:Person {name: 'Tom Hanks'})-[:ACTED_IN]->(movie1:Movie)<-[:ACTED_IN]-(coActor:Person)-[:ACTED_IN]->(movie2:Movie)<-[:ACTED_IN]-(coCoActor:Person)
WHERE tom <> coCoActor
AND NOT (tom)-[:ACTED_IN]->(:Movie)<-[:ACTED_IN]-(coCoActor)
RETURN coCoActor.name, count(coCoActor) as frequency
ORDER BY frequency DESC
LIMIT 5

其中一个“同事的同事”是汤姆·克鲁斯。现在让我们看看这两个汤姆之间有哪些电影和演员,以便我们可以找出谁可以介绍他们。
探索路径
MATCH (tom:Person {name: 'Tom Hanks'})-[:ACTED_IN]->(movie1:Movie)<-[:ACTED_IN]-(coActor:Person)-[:ACTED_IN]->(movie2:Movie)<-[:ACTED_IN]-(cruise:Person {name: 'Tom Cruise'})
WHERE NOT (tom)-[:ACTED_IN]->(:Movie)<-[:ACTED_IN]-(cruise)
RETURN tom, movie1, coActor, movie2, cruise

如您所见,这会返回多条路径。如果您曾经玩过凯文·贝肯六度分隔游戏,那么这种查看人与人之间存在多少跳数的概念正是图所描述的。您会注意到,我们的结果甚至返回了包含凯文·贝肯本人的路径。
通过这两个简单的 Cypher 语句,我们已经创建了两个推荐算法 - **接下来与谁会面/合作**以及**如何与他们会面**。
其他推荐
您可以将此处学习到的相同想法应用于许多其他用途,例如推荐产品和服务、查找您可能喜欢的餐厅或活动,或与拥有相似兴趣或技能的其他同事建立联系。我们将在此处专门提及一些您可以用来查找更多信息的资源。
餐厅推荐
我们有一些朋友及其最喜欢的餐厅、菜肴和地点的图。
这里要回答的一个实际问题,以图搜索的形式表达为
What Sushi restaurants are in New York that my friends like?
如何将其转换为相应的 Cypher 语句?
MATCH (person:Person {name: 'Philip'})-[:IS_FRIEND_OF]->(friend)-[:LIKES]->(restaurant:Restaurant)-[:LOCATED_IN]->(loc:Location {location: 'New York'}),
(restaurant)-[:SERVES]->(type:Cuisine {type: 'Sushi'})
RETURN restaurant.name, count(*) AS occurrence
ORDER BY occurrence DESC
LIMIT 5
可以轻松集成到此查询中的其他因素包括收藏、过敏症、评分以及距当前位置的距离。