2017-06-12 46 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