在 ElasticSearch 6 中创建父子关系时遇到问题

Having trouble creating Parent-Child Relationship in ElasticSearch 6

我目前正在 Udemy 上学习 ElasticSearch 课程,但该视频谈论的是 ElasticSearch 5,而我目前使用的是 ElasticSearch 6。我在将 parent/child 关系转换为新的关系时遇到了问题格式。

在视频中设置 FranchiseFilms(即分别为 Star WarsThe Jedi Returns

导师做了以下事情:

curl -H "Content-Type: application/json" -XPUT "127.0.0.1:9200/series" -d '
{
    "mappings": {
        "franchise": {},
        "film": {
            "_parent": {
                "type": "franchise"
            }
        }
    }
}'

然而,当我尝试添加映射时,出现以下错误:

➜  Downloads curl -H "Content-Type: application/json" -XPUT "127.0.0.1:9200/series?pretty" -d '
{
    "mappings": {
        "franchise": {},
        "film": {
            "_parent": {
                "type": "franchise"
            }
        }
    }
}'
{
  "error" : {
    "root_cause" : [
      {
        "type" : "illegal_argument_exception",
        "reason" : "Rejecting mapping update to [series] as the final mapping would have more than 1 type: [franchise, film]"
      }
    ],
    "type" : "illegal_argument_exception",
    "reason" : "Rejecting mapping update to [series] as the final mapping would have more than 1 type: [franchise, film]"
  },
  "status" : 400
}

我根据以下资源尝试了很多方法,但未能找到解决方案: https://www.elastic.co/blog/index-type-parent-child-join-now-future-in-elasticsearch https://www.elastic.co/guide/en/elasticsearch/reference/master/parent-join.html https://github.com/elastic/elasticsearch/issues/20257

TLDR:有人可以帮我将 ElastiSearch 5 中的父子关系转换为 ElasticSearch 6 中的正确方法吗?


下一步(验证):为了验证映射是否有效,导师随后执行了以下操作:

他得到以下JSON数据:

wget http://media.sundog-soft.com/es/series.json

从 JSON 文件中提取:

{ "create" : { "_index" : "series", "_type" : "franchise", "_id" : "1"} }
{ "id": "1", "title" : "Star Wars" }
{ "create" : { "_index" : "series", "_type" : "film", "_id" : "260", "parent" : "1" } }
{ "id": "260", "title" : "Star Wars: Episode IV - A New Hope", "year":"1977" , "genre":["Action", "Adventure", "Sci-Fi"] }

并通过执行以下操作批量导入数据:

➜  curl -H "Content-Type: application/json" -XPUT "127.0.0.1:9200/_bulk?pretty" --data-binary @series.json

在 Elasticsearch 6.0 中,有一些根本性的变化阻止了 parent/child 关系。

  1. 一个索引不能包含超过一种类型。阅读更多 here.
  2. Parent/child 关系已被删除,因此 _parent 字段也被删除。您必须改用连接字段 parent/child.

Parent/child 关系要求有两种不同的类型,并且这两种类型都在同一索引中定义。既然您不能在一个索引中包含多种类型,就无法像 5.x 和先前版本中那样支持 parent/child 关系。

您可以参考连接字段文档,了解如何对 parent/child 关系做类似的事情。但是现在,您必须在同一类型的单个 Elasticsearch 索引中定义两种类型的文档。请参阅示例,该示例解释了如何使用连接字段 here.

来模拟“一对多”类型的关系(1 个问题,与该问题相关的多个答案)

编辑:

使用 join field 针对 Elasticsearch 6.x 更新的示例如下所示。

删除现有索引(如果存在)。

curl -XDELETE "http://localhost:9200/series"

使用连接字段创建新索引,在 franchise & film:

之间建立连接关系
curl -XPUT "http://localhost:9200/series" -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "doc": {
      "properties": {
        "join_field": { 
          "type": "join",
          "relations": {
            "franchise": "film" 
          }
        }
      }
    }
  }
}'

您示例中的更新 series.json 将作为内联批量请求发送:

curl -XPOST "http://localhost:9200/_bulk" -H 'Content-Type: application/json' -d'
{ "create" : { "_index" : "series", "_type" : "doc", "_id" : "1"} }
{ "id": "1", "title" : "Star Wars", "join_field": "franchise" }
{ "create" : { "_index" : "series", "_type" : "doc", "_id" : "260", "routing" : "1" } }
{ "id": "260", "title" : "Star Wars: Episode IV - A New Hope", "year":"1977" , "genre":["Action", "Adventure", "Sci-Fi"], "join_field": {"name": "film", "parent": "1"} }
{ "create" : { "_index" : "series", "_type" : "doc", "_id" : "1196", "routing" : "1" } }
{ "id": "1196", "title" : "Star Wars: Episode V - The Empire Strikes Back", "year":"1980" , "genre":["Action", "Adventure", "Sci-Fi"], "join_field": {"name": "film", "parent": "1"} }
{ "create" : { "_index" : "series", "_type" : "doc", "_id" : "1210", "routing" : "1" } }
{ "id": "1210", "title" : "Star Wars: Episode VI - Return of the Jedi", "year":"1983" , "genre":["Action", "Adventure", "Sci-Fi"], "join_field": {"name": "film", "parent": "1"} }
{ "create" : { "_index" : "series", "_type" : "doc", "_id" : "2628", "routing" : "1" } }
{ "id": "2628", "title" : "Star Wars: Episode I - The Phantom Menace", "year":"1999" , "genre":["Action", "Adventure", "Sci-Fi"], "join_field": {"name": "film", "parent": "1"} }
{ "create" : { "_index" : "series", "_type" : "doc", "_id" : "5378", "routing" : "1" } }
{ "id": "5378", "title" : "Star Wars: Episode II - Attack of the Clones", "year":"2002" , "genre":["Action", "Adventure", "Sci-Fi", "IMAX"], "join_field": {"name": "film", "parent": "1"} }
{ "create" : { "_index" : "series", "_type" : "doc", "_id" : "33493", "routing" : "1" } }
{ "id": "33493", "title" : "Star Wars: Episode III - Revenge of the Sith", "year":"2005" , "genre":["Action", "Adventure", "Sci-Fi"], "join_field": {"name": "film", "parent": "1"} }
{ "create" : { "_index" : "series", "_type" : "doc", "_id" : "122886", "routing" : "1" } }
{ "id": "122886", "title" : "Star Wars: Episode VII - The Force Awakens", "year":"2015" , "genre":["Action", "Adventure", "Fantasy", "Sci-Fi", "IMAX"], "join_field": {"name": "film", "parent": "1"} }
'

上面的批量请求创建了一个特许经营权和与该特许经营权相关的多部电影。

要查询特许经营权 ID = 1 的所有电影,请使用以下父 ID 查询。

curl -XGET "http://localhost:9200/series/_search" -H 'Content-Type: application/json' -d'
{
  "query": {
    "parent_id": { 
      "type": "film",
      "id": "1"
    }
  }
}'

完成@Pranav Shukla 所说的如果您想查询给定电影所属的特许经营权(例如 "The Force Awakens"),您可以使用以下查询:

curl -XGET localhost:9200/series/_search?pretty -H 'Content-Type: application/json' -d '    
{                                          
  "query": {
    "has_child" : {
      "type": "film",
      "query": {
        "match": {
          "title": "The Force Awakens"
        }
      }
    }
  }
}'