【问题标题】:How to index documents containing nested properties with Lucene?如何使用 Lucene 索引包含嵌套属性的文档?
【发布时间】:2017-11-13 18:27:55
【问题描述】:

我会尽量减少我的情况:我正在构建一个带有搜索界面的 Web 应用程序(使用 Spring),让您可以搜索带注释/标记文本的语料库。在我的数据库 (MongoDB) 中,一个文档代表一本书的一页(总共约 8000 页)。

这是 JSON 中的 Document 结构示例(为简洁起见,我删除了很多元数据。另外,这很重要,“tokens”-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 索引中,文档并不代表整个页面,而只是带有标签的单词/标记。所以一个索引文档看起来像这样(为了便于阅读,用 JSON 语法表示):

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

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

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

【问题讨论】:

  • 这必须是纯lucene还是可以使用elasticsearch?
  • @stripybadger 好吧,如果可能的话,我想避免用越来越复杂的组件来炸毁我的应用程序 - 但如果你说它会让事情成为可能,我愿意研究当然。

标签: java search indexing lucene


【解决方案1】:

有没有办法在 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" }} 
          ]
        }
      }
    }
  }
}

【讨论】:

  • 很久以前的事了,抱歉。我现在接受了这个答案,因为它说的是真的:Lucene 不支持开箱即用的嵌套文档。它可以通过展平文档来完成,但自己做有点麻烦。 elasticsearchsolr 会自动为您执行此操作,但这意味着您的应用会产生一些开销,如果它只是一个小型应用,这可能不是您想要的。
猜你喜欢
  • 2011-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-23
  • 1970-01-01
  • 2020-11-23
  • 1970-01-01
相关资源
最近更新 更多