结合 Neo4j 和 Elasticsearch

Combining Neo4j and Elasticsearch

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

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

Neo4j 的好处(假设在用户个人资料中获取 posts)是您可以一次获取所有这些(还有个人资料图片和用户详细信息,如果您已经喜欢 post)。这是一个查询(密码命令)中的很多细节。现在,如果我们想为 Elasticsearch 输出提供相同级别的详细信息,我现在可以想到以下内容:

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

  2. 在 Elasticsearch 中存储 post id。填充搜索结果时,使用此 post id 从 neo4j 数据库中获取每个 post 的信息并显示结果。 (10 个结果 -> 10 个单独的调用,听起来又很低效)

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

除了这些还有什么解决办法吗?这些听起来有点低效。

这是一个基于意见的问题,因为它没有 "right" 答案,所以请准备好迎接 SO no-fun 锤子的崩溃......但我一直认为一对一(Elasticsearch 然后是 Neo)打孔是处理此问题的最佳方法:在 Elasticsearch 中索引属性,执行全文搜索以获得可能的 ID,然后构建一个 Cypher 匹配,将结果限制为 return编辑 ID。

在 Cypher 中,您可以使用 IN [] 到 return 在数组中匹配的记录。所以你可以做 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 的额外开销和更复杂的查询。

我也在寻找 Neo4J 和 Elasticsearch 的集成。我看过"Neo4j River Plugin for ElasticSearch"。但我不知道如何使用它。如果你们找到任何关于与 "Neo4j River Plugin for ElasticSearch" 集成的信息,请告诉我,这将非常有帮助。