这实际上更像是一个Lucene问题,但它是在neo4j数据库的上下文中。
我有一个数据库,它被划分为50个左右的节点类型(所以“其他类型的dbs中的”集合“或”表“)。每个属性都有一个需要索引的属性子集,有些属性名称相同,有些则没有。
搜索时,我总是希望找到特定类型的节点,而不是所有节点。
我可以看到三种组织方式:
每种类型一个索引,属性自然映射到索引字段:index'foo','id'='1234'
。
单个全局索引,每个字段映射到一个属性名称,以区分该类型将其包含为值('id'='foo:1234'
)的一部分,或者在返回后检查节点(我期望重复是非常罕见的。)
单个索引类型是字段名称的一部分:'foo.id'='1234'
。
创建后,数据库是只读的。
在便利性,尺寸/缓存效率或性能方面,其中之一是否有任何好处?
据我所知,对于第一个选项,neo4j将为每种类型创建一个单独的物理索引,这似乎不是最理想的。对于第三个,我最终得到的大多数lucene文档只有一小部分字段,不确定是否会影响任何内容。
答案 0 :(得分:2)
我最近遇到了这个问题,当时我正在通过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>
以到达模型节点,然后在标记为{{1的传出边缘上获取所有相邻节点}}。通过应用过滤器和其他复杂的遍历,可以进一步实现过滤查找。上述解决方案可防止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)个比较,你可能不会注意到任何差异。)
较小索引的另一个优点是操作系统缓存可能使查询运行得更快。
我会将两个不同的字段id
和type
编入索引而不是您的选项2和3,并搜索(id
:ID和type
:TYPE)但我不知道neo4j是否有可能。
答案 2 :(得分:1)
spring-data-neo4j正在使用第一种方法 - 它为每种类型创建不同的索引。所以我想这对于一般情况来说是个不错的选择。但正如你所说,在你的特殊情况下,它可能不是最理想的。我会运行一些基准测试来衡量性能。
顺便说一下,另外两个看起来有点人为。您可能在同一索引中索引完全不相关的信息,这听起来不对。