重新索引失败,数组映射到geo_point

时间:2019-03-18 19:16:27

标签: elasticsearch

我试图将一个字段的映射从文本类型更改为geo_point类型后重新索引。

源索引中的现有数据如下:

  "location" : {
    "lat_long" : [
      "49.266498",
      "-122.998938"
    ],

如何在_reindex api调用中遇到以下失败:

"cause": {
    "type": "mapper_parsing_exception",
    "reason": "failed to parse field [location.lat_long] of type [geo_point]",
    "caused_by": {
      "type": "parse_exception",
      "reason": "unsupported symbol [.] in geohash [49.228065]",
      "caused_by": {
        "type": "illegal_argument_exception",
        "reason": "unsupported symbol [.] in geohash [49.228065]"
      }
    }
  },

1 个答案:

答案 0 :(得分:1)

问题在于您的source_index(即latitude.lat_long)字段不符合geo_point数据类型所支持的四个有效表示形式中的任何一个。

因此,当您尝试重新建立索引时,转换将失败。

唯一适用的 string 表示形式应为以下格式"lat, lon",但是您拥有的表示形式是[ "lat", "lon" ],它只不过是字符串数组。

如果表示采用以下格式,则重新索引将成功执行。

"location" : {
    "lat_long" : "49.266498, -122.998938"
    ]
 }

作为解决方案,您可以执行以下步骤:

步骤1:创建Ingest Pipeline

执行以下查询,以创建将input format的{​​{1}}转换为如上所述的所需格式的管道

latitude.lat_long

步骤2:执行以下重新索引查询

PUT _ingest/pipeline/my-pipeline-geo
{
  "description" : "geo-point pipeline",
  "processors" : [
    {
        "script": {
          "lang": "painless",
          "source": "ctx.temp = \"\"; for (def item : ctx.location.lat_long) { if(ctx.temp==\"\") { ctx.temp += item } else { ctx.temp = ctx.temp + ', ' + item} }"
        }
      },
      {
        "remove": {
          "field": "location"
        }
      },
      {
        "set": {
          "field": "location.lat_long",
          "value": "{{temp}}"
        }
      },
      {
        "remove": {
          "field": "temp"
        }
      }
  ]
}

在重新索引步骤中,请注意我如何使用在步骤1 中创建的管道。 输出将采用我上面提到的格式。请花点时间阅读一下Elasticsearch中内置的Ingestion API

测试,验证并告诉我进展如何。