JavaNeo4J索引(使用Lucene)组织节点“类型”的好方法?
这实际上更像是一个Lucene问题,但它是在neo4j数据库的上下文中
我有一个分为50种左右节点类型的数据库(在其他类型的数据库中是“集合”或“表”)。每个属性都有需要索引的属性子集,有些共享相同的名称,有些不共享
搜索时,我总是希望找到特定类型的节点,而不是所有节点
我可以看到三种组织方式:
每种类型一个索引,属性自然映射到索引字段:索引'foo',
'id'='1234'
一个单一的全局索引,每个字段映射到一个属性名,以区分类型,或者将其作为值(
'id'='foo:1234'
)的一部分包含,或者在返回节点后检查它们(我希望重复的节点非常少)单个索引的类型是字段名的一部分:
'foo.id'='1234'
一旦创建,数据库将是只读的
在便利性、大小/缓存效率或性能方面,其中一个有什么好处吗
据我所知,对于第一个选项,neo4j将为每种类型创建单独的物理索引,这似乎不太理想。第三,我最终发现大多数lucene文档只有一小部分字段,不确定这是否会影响任何内容
# 1 楼答案
spring-data-neo4j使用的是第一种方法——它为每种类型创建不同的索引。所以我想这对一般情况来说是个不错的选择。但在你的特殊情况下,正如你所说,这可能是次优的。我会运行一些基准来衡量性能
另外两个,顺便说一句,似乎有点做作。你可能在同一个索引中索引完全不相关的信息,这听起来不对
# 2 楼答案
我最近在为Neo4j over REST构建
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:<model-name>
查找model_index
以到达模型节点,然后通过标记为instances
的传出边缘获取所有相邻节点。通过应用过滤器和其他复杂遍历,可以进一步实现过滤查找李>上述解决方案可以防止model_索引阻塞,因为它包含2x,并通过一个索引查找和单级遍历实现有效的记录查找
虽然在您的例子中,不同类型的节点彼此不相邻,但即使您想这样做,也可以通过简单地查找具有标记为
instances
的传入边的相邻节点来确定任意节点的类型。此外,我正在考虑合并SpringDataGraph的模式,即在每个实例节点上存储__type__
属性,以避免这种相邻节点的查找我目前正在将AREL翻译成几乎所有的小精灵脚本。你可以在https://github.com/yournextleap/activerecord-neo4j-adapter找到我的AR适配器的源代码
希望这有帮助,干杯!:)
# 3 楼答案
单个索引将比几个小索引小,因为一些数据(如术语词典)将被共享。然而,由于术语词典查找是一个O(lg(n))操作,在更大的术语词典中查找可能会慢一些。(如果您有50个索引,这只需要再进行6次比较(2^6>;=50),您可能不会注意到任何差异。)
较小索引的另一个优点是,OS缓存可能会使查询运行得更快
代替选项2和3,我将索引两个不同的字段
id
和type
,并搜索(id
:ID和type
:TYPE),但我不知道使用neo4j是否可行