这实际上更像是一个 Lucene 问题,但它是在 neo4j 数据库的上下文中。
我有一个数据库,分为 50 种左右的节点类型(其他类型的数据库中的“集合”或“表”)。每个都有一个需要索引的属性子集,有些共享相同的名称,有些则不需要。
在搜索时,我总是希望找到特定类型的节点,而不是跨越所有节点。
我可以看到三种组织方式:
每种类型一个索引,属性自然映射到索引字段:索引 'foo',
'id'='1234'
。单个全局索引,每个字段映射到一个属性名称,以区分类型或者将其作为值的一部分包含 (
'id'='foo:1234'
) 或在节点返回后检查它们(我希望重复的节点非常少)。单个索引,类型是字段名称的一部分:
'foo.id'='1234'
。
一旦创建,数据库就是只读的。
其中之一在便利性、大小/缓存效率或性能方面有什么好处吗?
据我了解,对于第一个选项,neo4j 将为每种类型创建一个单独的物理索引,这似乎不是最佳选择。对于第三个,我最终得到的大多数 lucene 文档只有一小部分字段,不确定这是否会影响任何内容。
最佳答案
我最近在通过 REST 为 Neo4j 构建一个 ActiveRecord
连接适配器时遇到了这个问题,用于 Rails 项目。由于 ActiveRecord
和 ActiveRelation
都与 SQL 语法紧密耦合,因此很难将所有内容都放入 NoSQL 中。可能不是最好的解决方案,但我是这样解决的:
- 创建了一个名为
model_index
的索引,它索引了两个键下的节点,type
和model
- 使用
type
键进行的索引查找目前只有一个值model
。这主要是为了实现SHOW TABLES
SQL 功能而引入的,它可以让我获得图中所有模型的列表。 - 使用
model
键进行索引查找时,值对应于我系统中的不同型号名称。这主要是为了实现DESC <TABLENAME>
功能。 - 在
CREATE TABLE
中创建每个表时,都会创建一个节点,其中表定义属性存储在节点属性中。 - 创建的节点在
model_index
下索引为type:model
和model:<model-name>
。这会在“表”列表中启用新创建的模型,并且还允许通过使用model
键的索引查找直接到达模型节点。 - 对于每
model
创建的每条记录(在您的情况下键入),将创建标记为instances
的传出边,从模型节点定向到此新记录。v[123] :=> [instances] :=> v[245]
其中v[123]代表模型节点,v[245]代表v[123]类型的一条记录。 - 现在,如果您想要获取指定类型的所有实例,您可以使用
model_index
查找model:<model-name>
以到达模型节点,然后获取标记为instances
的传出边上的所有相邻节点。通过应用过滤器和其他复杂的遍历,可以进一步实现过滤查找。
上述方案避免了model_index的阻塞,因为它包含2x,通过一次索引查找和单层遍历实现了有效的记录查找。
虽然在您的情况下,不同类型的节点彼此不相邻,但即使您想这样做,您也可以通过简单地查找带有标记为 instances
的传入边的相邻节点来确定任意节点的类型。此外,我正在考虑合并 SpringDataGraph 在每个实例节点上存储 __type__
属性的模式,以避免这种相邻节点查找。
我目前正在将几乎所有内容的 AREL 翻译成 Gremlin 脚本。你可以在 https://github.com/yournextleap/activerecord-neo4j-adapter 找到我的 AR 适配器的源代码
希望这对您有所帮助,干杯! :)
关于java - Neo4j 索引(使用 Lucene)- 组织节点 "types"的好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9879457/