如何使用Lucene索引包含嵌套属性的文档?

时间:2017-06-12 10:04:27

标签: java search indexing lucene

我会尝试将我的案例简化为必要:我正在构建一个带有搜索界面的Webapp(带Spring),可以搜索带注释/已标记文本的语料库。在我的数据库(MongoDB)中,一个文档代表一个书籍集合的一页(总共约8000页)。

以下是JSON中的Document结构示例(为简洁起见,我删除了大量元数据。此外,这很重要,"令牌" -array在大多数情况下最多包含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索引中,文档不代表整个页面,但只有一个单词/标记表示&# 39; s标签。所以一个索引文档看起来像这样(用JSON语法表示以便于阅读):

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

...是的,Lucene允许我多次使用一个字段。所以现在我可以搜索一个单词及其标签,并通过它的ID获取我的数据库中页面对象的引用。但这有点丑陋有两个原因:我现在有两个完全不同的文档表示(DB和Lucene索引),并且处理一个复杂的查询,就像我上面提到的那样,我必须查询单词并且它是&#39 ; s标签然后进一步手动检查检索到的文档中的命中的上下文。

所以我的问题是:有没有办法在Lucene中索引包含字段/属性的文档,这些字段/属性的值是嵌套对象,而这些对象又具有某些属性?

1 个答案:

答案 0 :(得分: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" }} 
          ]
        }
      }
    }
  }
}