结合Neo4j和Elasticsearch

时间:2015-01-22 17:26:34

标签: elasticsearch neo4j cypher

我使用Neo4j作为我的主数据库。它是一个很好的图形数据库,可以很好地控制节点之间的连接。但是,它似乎在搜索全文(网站上的搜索功能)方面缺乏高度。因此,我正在考虑使用Elasticsearch在我的应用程序上创建搜索功能。但这样做有一些问题。我们假设我们正在搜索用户帖子。在neo4j帖子中可以有以下模型。

(post)<-[:AUTHOR]-(user)
(post)-[:LIKED_BY]->(otherusers)
(post)-[:COMMENTED_BY]->(otherusers)
(post)-[:HAS_PHOTO]->(photos)

关于Neo4j的好处(让我们在用户个人资料中发帖时说)就是你可以一次抓住所有这些内容(同时也可以了解个人资料和用户详细信息,如果你有已经喜欢这个帖子了。这是一个查询(cypher命令)中的很多细节。现在,如果我们想为Elasticsearch输出提供相同级别的详细信息,我现在可以想到以下内容:

  1. 将所有内容存储在Neo4j和Elasticsearch中。搜索文本时,列出elasticsearch本身的结果。但是仍然存在一些问题,例如,如果用户已经喜欢该帖子(这可能需要再次查询每个帖子的内容?这听起来不太好)

  2. 在Elasticsearch中存储帖子ID。填充搜索结果时,使用此帖子ID从neo4j数据库中获取每个帖子的信息并显示结果。 (10个结果 - > 10个单独的电话,再次听起来非常低效)

  3. 获取Elasticsearch提供的ID列表,并对neo4j进行1次调用并获取结果(不知道如何执行此操作或是否存在性能问题)。密码参考可能会有所帮助。

  4. 除此之外的任何解决方案?这听起来有点低效。

2 个答案:

答案 0 :(得分:8)

这是一个基于意见的问题,因为它没有&#34;权利&#34;回答,所以准备好SO无趣的锤子崩溃......但是我一直认为一两(Elasticsearch然后Neo)打击是解决这个问题的最佳方法:Elasticsearch中的索引属性,执行全文搜索以获取可能的ID,然后构建Cypher匹配,将结果限制为返回的ID。

在Cypher中,您可以使用IN []返回数组中匹配的记录。所以你可以做MATCH (u:Student { age: 30 }) WHERE ID(u) IN [1, 2, 3, 4] RETURN u。因此,将Elasticsearch与Neo集成的技巧是使围绕ES结果构建Cypher查询变得容易。我真的没有这方面的提示,因为这取决于你的语言和司机。

在Neo4j.rb中,我正在考虑尝试自动执行此操作,以便您可以执行此操作:

student.lessons(:l).where(name: 'Chris').to_a

...并且它知道Lesson模型正在使用Elasticsearch,执行查询,然后更改用户的查询,因此它实际上是这样的:

student.lessons(:l).where('ID(l) IN {elasticsearch_results}').params(elasticsearch_results: [1, 2, 3, 4]).to_a`

我一直在使用Searchkick与Neo进行全文搜索,而且它一直很顺利。我认为这是可行的。不是你问题的解决方案,而是我如何思考它,所以也许它会给你一些想法。

值得注意的是,Neo确实使用=~进行模糊搜索,它只是没有使用索引,因此可能会遇到性能损失。但这可能不是问题,因为您可以通过向查询的其他部分添加更多信息来过滤Cypher必须检查的节点和属性的数量。您应该对数据进行一些基准测试,以确定是否需要增加Elasticsearch的开销和更复杂的查询。

答案 1 :(得分:3)

我也在寻找Neo4J&amp; Elasticsearch集成。我见过ElasticSearch&#34;的Neo4j River插件。但我不知道如何使用它。如果你们有任何关于与ElasticSearch&#34;的Neo4j River插件集成的信息,请告诉我,这将非常有帮助。