2012-04-02 147 views
9

说,而不是文件我有我需要存储在Lucene索引中的小树。我该如何去做呢?如何将树数据存储在Lucene/Solr/Elasticsearch索引或NoSQL数据库中?

在树的示例节点:

class Node 
{ 
    String data; 
    String type; 
    List<Node> children; 
} 

在上述节点中的“数据”成员变量是字的空间分隔的字符串,以使得需要进行全文检索。 “类型”成员变量只是一个单词。

搜索查询将是一棵树本身,将搜索每个节点中的数据和类型以及匹配树的结构。在针对子节点进行匹配之前,查询必须首先匹配父节点数据和类型。数据值的近似匹配是可以接受的。

索引这类数据的最佳方法是什么?如果Lucene不直接支持索引这些数据,那么可以通过Solr或Elasticsearch来完成吗?

我快速浏览了neo4j,但它似乎将整个图存储在数据库中,而不是大型集合(例如数十亿或数万亿)的小型树结构。或者我的理解错了?

另外,是不是基于Lucene的NoSQL解决方案更适合这个?

+0

您在搜索时发现了什么?如果您将NodeB作为NodeA的子节点,并且NodeB具有文本FOO,则在搜索FOO时,是否要返回NodeB或NodeA? – sbridges 2012-04-02 02:32:53

+0

查询将与树结构和树数据匹配。因此,如果NodeA中的数据已经匹配,那么NodeB中FOO的出现将构成完全匹配。 – 2012-04-02 02:40:33

+0

你是说FOO必须在NodeA和NodeB中?或者该类型必须在NodeA中匹配,但您不关心在NodeB中是否匹配类型。 – sbridges 2012-04-02 02:44:41

回答

8

另一种方法是存储在树中当前节点的位置的表示。例如,第14棵树的第1级节点的第3级节点的第17叶将被表示为014.001.003.017

假设'treepath'是树位置的字段名称,您将在'treepath:014 *'上查询以找到第14棵树中的所有节点和树叶。同样,要查找第14棵树的所有孩子,您可以在'treepath:014. *'上查询。

这种方法的主要问题是,移动分支需要在移动分支后重新排序每个分支。如果你的树木相对静止,那在实践中可能只是一个小问题。

(我已经看到这种做法称为无论是“路径枚举”或“杜威十进制”表示。)

+0

谢谢马克!这就是我为解决这个问题而采取的方法。 – 2012-04-18 21:49:18

+0

您好@GolamKawsar,这种方法是否有助于在每个层次上汇总层次结构? – 2017-04-26 10:17:54

2

我建议Neo4j。毕竟,树只是一个特殊的约束图。

检查出是否应该保存在一棵树上的Neo4j这个大讨论:

http://www.mail-archive.com/[email protected]/msg03256.html

+0

感谢您的回答,但您的链接已损坏。此外,Neo4j是否允许存储数十亿(或数万亿)的小树木被索引?我希望能够搜索树,包括它们的结构和存储在节点中的文本。 – 2012-04-03 14:01:54

+0

链接没有损坏,我刚刚检查过。 – 2012-04-04 10:11:42

+0

以下是更多可以找到该讨论主题的地方:http://lists.neo4j.org/pipermail/user/2010-April/003313.html http://neo4j.org/nabble/#nabble-td700300 – 2012-04-04 10:16:22

3

这要求和解决方案是在这里拍摄的:Proposal for nested docs

这种设计是随后由内核Lucene和Elastic Search实现。 的BlockJoinQuery是核心Lucene的实施和弹性搜索看看有没有实现所列出的位置:Elastic search nested docs

+0

谢谢,ES/Lucene的本地解决方案比任何“hacky”解决方案都要好! – 2012-05-21 16:57:27

相关问题