2012-04-02 125 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

相關問題