2017-06-12 107 views
0

我會盡量減少我的情況:我正在構建一個帶有搜索界面的Web應用程序(帶有Spring),它允許您搜索註釋/標記文本的語料庫。在我的數據庫(MongoDB)中,一個文檔代表書籍集合的一頁(總共約8000頁)。如何使用Lucene索引包含嵌套屬性的文檔?

這裏是JSON文檔結構的一個例子(爲了簡潔起見,我刪除了很多元數據,而且這很重要,在大多數情況下,「標記」 - 數組最多包含700個對象):

{ 
    "_id" : ObjectId("5622c29eef86d3c2f23fd62c"), 
    "scanId" : "592ea208b6d108ee5ae63f79", 
    "volume" : "Volume I", 
    "chapters" : [ 
     "Some Chapter Name" 
    ], 
    "languages" : [ 
     "English", 
     "German" 
    ], 
    "tokens" : [ 
     { 
      "form" : "The", 
      "index" : 0, 
      "tags" : [ 
       "ART" 
      ] 
     }, 
     { 
      "form" : "house", 
      "index" : 1, 
      "tags" : [ 
       "NN", 
       "NN_P" 
      ] 
     }, 
     { 
      "form" : "is", 
      "index" : 2, 
      "tags" : [ 
       "V", 
       "CONJ_C" 
      ] 
     } 
    ] 
} 

所以你看我沒有一個純文本,在這裏。我現在想用Lucene建立一個索引來快速搜索這個數據庫。問題是我希望能夠搜索某些單詞,它們的標籤以及它周圍的上下文。就像「給我包含'House'這個詞的所有文件都標記爲'NN',後面跟着一個標有'V'的單詞'」。我找不到用本地Lucene功能來索引這些子結構的方法。

我試圖做的至少能夠搜索單詞和它們的標籤如下:在我的Lucene索引中,文檔不代表整個頁面,而只是一個帶有標籤的單詞/標記。所以一個索引文件看起來像這樣(以JSON語法表達了可讀性):

{ 
    "token" : "house", 
    "tag" : "NN", 
    "tag" : "NN_P", 
    "index" : 1, 
    "pageId" : "5622c29eef86d3c2f23fd62c" 
} 

...是的,Lucene的允許我使用一個場多次。所以現在我可以搜索一個單詞,它是標籤,並通過它的ID獲取對我的數據庫中的頁面對象的引用。但這非常醜陋,原因有兩個:我現在有兩個完全不同的文檔表示(DB和Lucene索引),並處理複雜的查詢,就像我上面提到的那樣,我必須查詢單詞和它的標記,然後進一步手動檢查檢索到的文檔中匹配的上下文。

所以我的問題是:是否有一種方法來索引文件在Lucene中包含字段/屬性的值是嵌套的對象,反過來具有某些屬性?

+0

這是否必須是純粹的lucene或您可以使用elasticsearch? – stripybadger

+0

@stripybadger當然,如果可能的話,我想盡量避免使用更多更復雜的組件來渲染我的應用程序 - 但如果您說它會讓事情成爲可能,那麼當然,我會願意考慮它。 – mumpitz

回答

0

有沒有一種方法來索引文件在Lucene中包含字段/屬性的值是嵌套的對象,而該對象又具有某些屬性?

Elasticsearch當然可以讓你做到這一點。我認爲可以在純lucene中完成所有這些工作,但可能需要付出一些努力。

基本上,你需要使用「嵌套」查詢:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html

PUT /my_index 
{ 
    "mappings": { 
     "type1" : { 
      "properties" : { 
       "tokens" : { 
        "type" : "nested" 
       } 
      } 
     } 
    } 
} 

這告訴ES索引此字段的內容作爲單獨的文件列表,讓你對他們單獨使用查詢「嵌套'查詢:

GET my_index/_search 
{ 
    "query": { 
    "nested": { 
     "path": "tokens", 
     "query": { 
     "bool": { 
      "must": [ 
      { "match": { "tokens.form": "house" }}, 
      { "match": { "tokens.tags": "NN" }} 
      ] 
     } 
     } 
    } 
    } 
} 
+0

很久以前,對不起。我現在接受了這個答案,因爲它說的是真的:Lucene不支持嵌入文件。它*可以通過展開文檔來完成,但自己做這件事有點難。 ** elasticsearch **和** solr **會自動爲您執行此操作,但這意味着您的應用程序會有一些開銷,如果它只是一個小應用程序,可能不是您想要的。 – mumpitz