Neo4j索引(与Lucene) - 组织节点“类型”的好方法?

时间:2012-03-26 20:39:13

标签: java lucene indexing neo4j

这实际上更像是一个Lucene问题,但它是在neo4j数据库的上下文中。

我有一个数据库,它被划分为50个左右的节点类型(所以“其他类型的dbs中的”集合“或”表“)。每个属性都有一个需要索引的属性子集,有些属性名称相同,有些则没有。

搜索时,我总是希望找到特定类型的节点,而不是所有节点。

我可以看到三种组织方式:

  • 每种类型一个索引,属性自然映射到索引字段:index'foo','id'='1234'

  • 单个全局索引,每个字段映射到一个属性名称,以区分该类型将其包含为值('id'='foo:1234')的一部分,或者在返回后检查节点(我期望重复是非常罕见的。)

  • 单个索引类型是字段名称的一部分:'foo.id'='1234'

创建后,数据库是只读的。

在便利性,尺寸/缓存效率或性能方面,其中之一是否有任何好处?

据我所知,对于第一个选项,neo4j将为每种类型创建一个单独的物理索引,这似乎不是最理想的。对于第三个,我最终得到的大多数lucene文档只有一小部分字段,不确定是否会影响任何内容。

3 个答案:

答案 0 :(得分:2)

我最近遇到了这个问题,当时我正在通过REST为Neo4j构建一个ActiveRecord连接适配器,以便在Rails项目中使用。由于ActiveRecordActiveRelation两者都与SQL语法紧密耦合,因此很难将所有内容都安装到NoSQL中。可能不是最好的解决方案,但这就是我解决它的方法:

  1. 创建了一个名为model_index的索引,该索引为两个密钥下的节点编制索引,typemodel
  2. 使用type键进行索引查找当前仅使用一个值model。这主要是为了实现SHOW TABLES SQL功能而引入的,它可以为我提供图表中所有模型的列表。
  3. 使用model键进行索引查找,并使用与系统中不同型号名称对应的值。这主要是为了实现DESC <TABLENAME>功能。
  4. CREATE TABLE中创建每个表时,会创建一个节点,其中表定义属性存储在节点属性中。
  5. 已创建的节点在model_index下以type:modelmodel:<model-name>编入索引。这将在“表”列表中启用新创建的模型,并允许通过使用model键的索引查找直接到达模型节点。
  6. 对于每model创建的每条记录(在您的情况下为类型),将创建一个标记为instances的传出边缘,从模型节点指向此新记录。 v[123] :=> [instances] :=> v[245]其中v [123]表示模型节点,v [245]表示v [123]类型的记录。
  7. 现在,如果要获取指定类型的所有实例,可以使用model_index查找model:<model-name>以到达模型节点,然后在标记为{{1的传出边缘上获取所有相邻节点}}。通过应用过滤器和其他复杂的遍历,可以进一步实现过滤查找。
  8. 上述解决方案可防止model_index阻塞,因为它包含2x并通过一次索引查找和单级遍历实现有效的记录查找。

    虽然在你的情况下,不同类型的节点彼此不相邻,但即使你想这样做,你也可以通过简单地查找它的相邻节点来确定任意节点的类型,其边缘标记为{{ 1}}。此外,我正在考虑合并SpringDataGraph的模式,在每个实例节点上存储instances属性,以避免这种相邻节点查找。

    我目前正在将AREL翻译成几乎所有的Gremlin脚本。您可以在https://github.com/yournextleap/activerecord-neo4j-adapter

    找到我的AR适配器的源代码

    希望这有帮助,干杯! :)

答案 1 :(得分:1)

单个索引将小于几个小索引,因为某些数据(例如术语词典)将被共享。但是,由于术语字典查找是O(lg(n))操作,因此在较大术语字典中查找可能会慢一些。 (如果你有50个索引,这只需要6(2 ^ 6> = 50)个比较,你可能不会注意到任何差异。)

较小索引的另一个优点是操作系统缓存可能使查询运行得更快。

我会将两个不同的字段idtype编入索引而不是您的选项2和3,并搜索(id:ID和type:TYPE)但我不知道neo4j是否有可能。

答案 2 :(得分:1)

spring-data-neo4j正在使用第一种方法 - 它为每种类型创建不同的索引。所以我想这对于一般情况来说是个不错的选择。但正如你所说,在你的特殊情况下,它可能不是最理想的。我会运行一些基准测试来衡量性能。

顺便说一下,另外两个看起来有点人为。您可能在同一索引中索引完全不相关的信息,这听起来不对。