4

我正在做一个项目来索引弹性搜索(版本 6)中网站的问题和答案,以进行搜索。

我首先想到创建两个索引,如下所示,一个用于问题,一个用于答案。

问题映射:

{"mappings": {
"question": {
  "properties": {
    "title":{
        "type":"text"
    },
    "question": {
      "type":  "text"
    },
    "questionId":{
        "type":"keyword"
    }
  }
}
}
}

答案映射:

{"mappings": {
    "answer": {
      "properties": {
        "answer":{
            "type":"text"
        },
        "answerId": {
          "type":  "keyword"
        },
        "questionId":{
            "type":"keyword"
        }
      }
    }
  }
}

我使用多匹配查询以及 term 和 top_hits 聚合来搜索索引问答(参考问题)。我使用这种方法从搜索结果中删除重复项。作为答案或同一问题的问题本身可以出现在结果中。我只希望结果中的每个问题都有一个条目。我面临的问题是对结果进行分页。在弹性搜索中没有可能对聚合进行分页。它只能对命中而不是聚合进行分页。

然后我想到将问题和答案保存在一个文档中,将答案保存在 Json 数组中。这种方法的问题是没有干净的方法来添加、删除、更新给定问题文档中的特定答案。我发现的唯一方法是使用 groovy 脚本(提到的问题)。在 elasticsearch v6 AFAIK 中已弃用。

有没有更好更干净的方法来设计这个?谢谢。

4

1 回答 1

6

亲子关系

使用父子关系。它类似于嵌套模型,并允许将一个实体与另一个实体关联。您可以以一对多的关系将一种文档类型与另一种文档类型相关联。有关此处的更多信息:https ://www.elastic.co/guide/en/elasticsearch/guide/current/parent-child.html

可以添加、更改或删除子文档,而不会影响父文档或其他子文档。您可以使用Scroll API对父文档进行分页。可以使用has_parent连接检索子文档。

权衡:您不必处理重复和分页问题,​​但父子查询可能比等效的嵌套查询慢 5 到 10 倍。

您的映射可能如下所示:

PUT /my-index
{
  "mappings": {
    "question": {
      "properties": {
        "title": {
          "type": "text"
        },
        "question": {
          "type": "text"
        },
        "questionId": {
          "type": "keyword"
        }
      }
    },
    "answer": {
      "_parent": {
        "type": "question"
      },
      "properties": {
        "answer": {
          "type": "text"
        },
        "answerId": {
          "type": "keyword"
        },
        "questionId": {
          "type": "keyword"
        }
      }
    }
  }
}
于 2018-06-25T16:41:20.293 回答