为什么我不能在Elasticsearch中混合我的数据类型?

时间:2019-03-02 22:14:14

标签: elasticsearch

当前,我正在尝试在此处实现汽车示例的一种变体:

https://www.elastic.co/blog/managing-relations-inside-elasticsearch

如果我跑步:

PUT /vehicle/_doc/1
{  
   "metadata":[  
      {  
         "key":"make",
         "value":"Saturn"
      },
      {  
         "key":"year",
         "value":"2015"
      }
   ]
}

代码正常工作。

但是如果我删除索引并将2015从字符串更改为数字:

DELETE /vehicle
PUT /vehicle/_doc/1
{  
   "metadata":[  
      {  
         "key":"make",
         "value":"Saturn"
      },
      {  
         "key":"year",
         "value":2015
      }
   ]
}

我收到以下错误消息:

  

{“错误”:{       “根本原因”: [         {           “ type”:“ illegal_argument_exception”,           “ reason”:“不同类型的映射器[metadata.value],current_type [long],merged_type [text]”         }       ],       “ type”:“ illegal_argument_exception”,       “ reason”:“不同类型的映射器[metadata.value],current_type [long],merged_type [text]”},“ status”:400}

如何解决此错误?

1 个答案:

答案 0 :(得分:2)

PUT /vehicle/_doc/1
{  
   "metadata":[  
      {  
         "key":"make",
         "value":"Saturn"
      },
      {  
         "key":"year",
         "value":2015
      }
   ]
}

删除索引,然后尝试按上述方法索引新文档后,将执行以下步骤:

  1. 当Elastic无法找到名称为vehicle的索引并且启用了自动索引创建(默认情况下启用)时,它将创建一个名为vehicle的新索引。
  2. 基于输入文档,elastic现在尝试最好地猜测文档字段的数据类型。这就是dynamic field mapping
  3. 对于上述文档,由于metadata是对象数组,因此假设字段metadata的数据类型为object
  4. 现在是确定单个对象字段的数据类型的步骤。当遇到第一个对象时,它将找到两个字段keyvalue。这两个字段都具有字符串值(分别为makeSaturn),因此弹性将两个字段的数据类型标识为text
  5. 弹性然后尝试如下定义映射:

      {
        "properties": {
          "metadata": {
            "properties": {
              "key": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "value": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              }
            }
          }
        }

当遇到第二个对象,其中value字段的值为数字(2015)时,它将猜测数据类型为long。这导致与先前标识的数据类型text相冲突。字段不能为混合数据类型。数据类型很严格,因此会出错。

要解决该错误,您需要确保每个对象的字段输入值具有相同的类型,如下所示:

PUT /vehicle/_doc/1
{  
   "metadata":[  
      {  
         "key":"make",
         "value":2016
      },
      {  
         "key":"year",
         "value":2015
      }
   ]
}

在上面,它最好用作:

PUT /vehicle/_doc/1
{  
   "metadata":[  
      {  
         "make":"Saturn",
         "year": 2015
      }
   ]
}