dot Redis 8 来了——而且它是开源的

了解更多

多模型实战:同时使用 RedisGraph 和 RediSearch

在 RedisConf19 大会上,我演示了一种在 RedisGraph 节点上运行 RediSearch 全文搜索的解决方案。大会前几天有些模糊,但现在,几周后,我意识到我们应该更多地解释我们是如何做到这一点的,并发布源代码。

在此演示中,我展示了一个小型界面,您可以通过该界面搜索动物并查看它们如何通过生物分类系统(界、门、纲、目等)相关联。全文搜索部分基于维基百科的第一个英文段落。例如,假设您搜索“cat house pet”(家猫,Felis catus)和“baleen blue”(蓝鲸,Balaenoptera musculus),您会发现它们都只是哺乳动物;而如果您搜索“cat house pet”和“snow central asia cat”(雪豹,Panthera uncia),您会发现它们都属于同一个科:猫科(Felidae)。

这个演示项目出奇地简单,但我应该指出,在撰写本文时,RediSearch 和 RedisGraph 之间的集成仍处于早期阶段,尚未准备好投入生产。我鼓励您探究这种方法是否能满足您的需求,同时理解 RediSearch 和 RedisGraph 之间的集成将在未来几个月内成熟和扩展。

与此同时,我们来谈谈演示的组成部分。要完成的第一件事是基于仓库中的正确分支构建 RediSearch 和 RedisGraph。对于 RediSearch,只需使用 当前 master 分支,而对于 RedisGraph,您需要 redisconf 分支。如果您想为自己的需求复制此解决方案,则需要从源代码构建这两个模块。RedisGraph 网站RediSearch 网站上都有关于如何执行此操作的详细说明,这需要一些时间,但并不困难。

在您的 redis.conf 文件中,您需要确保 RedisGraph 在 RediSearch 之前加载。为此,请打开 redis.conf 文件并在模块部分,将 RediSearch 的 loadmodule 指令放在 RedisGraph 的前面。这样,当 RedisGraph 加载时,它将检测到搜索模块的存在。完成 redis.conf 编辑后,您可以继续重启 Redis 服务器。

演示仓库 中,我包含了我们通过使用 redisgraph-bulk-loader 脚本将以下 CSV 数据加载到 RedisGraph 中整理而成的数据集。该数据集仅包含动物界中的哺乳动物,因为哺乳动物以外的动物数据质量较低(非哺乳动物物种很少有好的维基百科描述)。

数据加载方法如下

$ cd redisgraph-bulk-loader/
$ python3 bulk_insert.py MAMMALS -q -n /path/to/demo/dataload/Class.csv -n /path/to/demo/dataload/Family.csv -n /path/to/demo/dataload/Genus.csv -n /path/to/demo/dataload/Order.csv -n /path/to/demo/dataload/Species.csv -r /path/to/demo/dataload/IN_CLASS.csv -r /path/to/demo/dataload/IN_FAMILY.csv -r /path/to/demo/dataload/IN_GENUS.csv -r /path/to/demo/dataload/IN_ORDER.csv -a yourpassword
创建了 1 个带有标签 'Class' 的节点
创建了 157 个带有标签 'Family' 的节点
创建了 1272 个带有标签 'Genus' 的节点
创建了 29 个带有标签 'Order' 的节点
创建了 5616 个带有标签 'Species' 的节点
创建了 29 个类型为 'IN_CLASS' 的关系
创建了 1272 个类型为 'IN_FAMILY' 的关系
创建了 5616 个类型为 'IN_GENUS' 的关系
创建了 157 个类型为 'IN_ORDER' 的关系
图 'MAMMALS' 构建完成:创建了 7075 个节点,创建了 7074 个关系,耗时 0.443749 秒
$ redis-cli -a yourpassword GRAPH.QUERY MAMMALS "CALL db.idx.fulltext.createNodeIndex('Species','description')"
警告:在命令行界面使用 '-a' 或 '-u' 选项指定密码可能不安全。
1) (空列表或集合)
2) (空列表或集合)
3) 1) "查询内部执行时间:324.970000 毫秒"

(要点:https://gist.github.com/stockholmux/0727a4a784a46f8cb9e8329d393a513a)

此时,键 MAMMALS 包含了我们整个图。有几个重要注意事项

  • bulk_insert.py 脚本中的 -q 开关非常重要,因为它允许在读取 CSV 时进行智能引用。
  • redis-cli 调用会一次性对所有节点进行批量索引,因此,实际上它为全文搜索索引了 7,000 多个文档。

现在,让我们启动并运行一个用户界面。与几乎所有 Node.js 应用一样,我们从 npm install 开始。这可能需要几秒钟,因为我们不仅要管理 Node.js 的服务器端文件,还要管理前端的 Vue.js 组件。如果您最近没有花太多时间在前端 Javascript 世界,它已经不再是 FTP 和 HTML 文件的事情了。现代前端开发者确实认真对待他们的工具,所以我们需要安装 Vue CLI(我建议按照 Vue CLI 入门指南进行操作)。

安装好前端工具后,回到 npm,运行以下命令构建前端:

$ npm run build

这将创建 dist 目录,我们将从该目录提供所有前端文件。现在我们的数据已存入 Redis,前端文件也已准备好提供服务,我们可以启动服务器了

$ node server.js -p 6379 -a yourpassword -h yourhostOrlocalhost

让我们暂停片刻,介绍一下我们刚刚启动的这个服务器的一些要点。它基于 Express.js 构建,主要使用 websockets 进行来回通信。我还集成了 Visible Engine 调试工具,您可以在单独的浏览器窗口中查看正在执行的命令。您可以通过将浏览器指向 http://localhost:4444 来体验该演示。

总而言之,对于它所实现的功能而言,代码非常短——只有 75 行。我们的解决方案不需要那么长,因为我们真正做的就是接受 websocket 连接,根据传递的消息运行 Redis 命令,然后将带有结果的消息传回。Redis(Graph) 在这里完成了所有繁重的工作。让我们看看我们正在执行的命令。

要搜索关键字,我们运行此命令

> GRAPH.QUERY MAMMALS "CALL db.idx.fulltext.queryNodes('Species','cat house pet')"

这相当简单。我们的键是 MAMMALS,我们使用特殊的 Cypher 语法 CALL 调用一个特定函数,该函数传入我们正在查找的节点的标签以及最后的实际搜索字符串。您可以传入有效的 RediSearch 查询,但请记住,目前这仅支持全文搜索,因此不要使用地理空间、标签或数值子句。

一旦我们确定了要比较的两种动物,我们就使用一个直接的 Cypher 查询

> GRAPH.QUERY MAMMALS "MATCH (s:Species)-[*]->(x)<-[*]-(c:Species) WHERE c.fullname = 'Felis catus' AND s.fullname = 'Balaenoptera borealis'  RETURN x.name, labels(x) LIMIT 1"

server.js 文件中,这些查询表示为 Javascript 模板字符串。没有任何隐藏的内容,它只是通过字符串插值将用户输入转换为查询。然而,如果在生产环境中部署类似的东西,您需要谨慎处理用户输入。

如果您打算修改前端代码,请确保编辑 /src 目录,而不是 /dist。编辑后,您需要再次运行 npm run build,或者使用开发服务器(npm run serve),它会自动编译对前端代码的更改并在另一个端口上提供服务。同样,这里没有太多复杂的内容,这是一个非常标准的 Vue.js 和 Bootstrap 应用。唯一真正相关的文件是 /src/App.js、/src/components/panels.vue/src/components/search.vue

就是这样。这是一个简单的演示,展示了一个强大的功能,它集成了两种不同的模型——图和全文搜索。我鼓励您尝试这个演示并替换为您自己的数据集。