Elasticsearch映射 - 同一字段中的不同数据类型

时间:2014-11-14 12:59:27

标签: elasticsearch elasticsearch-mapping

我正在尝试创建一个映射,允许我有一个如下所示的文档:

{
    "created_at" : "2014-11-13T07:51:17+0000",
    "updated_at" : "2014-11-14T12:31:17+0000",
    "account_id" : 42,
    "attributes" : [
    {
        "name" : "firstname",
        "value" : "Morten",
        "field_type" : "string"
    },
    {
        "name" : "lastname",
        "value" : "Hauberg",
        "field_type" : "string"
    },
    {
        "name" : "dob",
        "value" : "1987-02-17T00:00:00+0000",
        "field_type" : "datetime"
    }
]

}

attributes数组必须是嵌套类型和动态类型,因此我可以向数组中添加更多对象,并按field_type值对其进行索引。

这甚至可能吗?

我一直在关注dynamic_templates。我能用吗?

2 个答案:

答案 0 :(得分:4)

否 - 您不能为同一类型中的同一字段提供不同的数据类型。

e.g。字段index/type/value不能同时是字符串和日期。


可以使用dynamic template根据字段名称的格式设置数据类型和分析器

例如: 设置字段名称以“_dt”结尾的所有字段,以键入datetime

但是这对你的场景没有帮助,一旦设置了数据类型你就无法改变它。

答案 1 :(得分:2)

如果愿意,您可以 使用多字段映射和ignore_malformed参数将多个数据类型索引到同一个字段中输入特定查询(例如比较)。

这将允许elasticsearch填充与每个输入相关的字段,而忽略其他输入。这也意味着您无需在索引代码中执行任何操作即可处理不同的类型。

例如,对于一个名为user_input的字段,您希望能够对日期或整数范围进行查询(如果用户输入的是该字段),或者进行常规文本搜索(如果用户输入了一个字符串),则可以类似于以下内容:

PUT multiple_datatypes
{
  "mappings": {
    "_doc": {
      "properties": {
        "user_input": {
          "type": "text",
          "fields": {
            "numeric": {
              "type": "double",
              "ignore_malformed": true
            },
            "date": {
              "type": "date",
              "ignore_malformed": true
            }
          }
        }
      }
    }
  }
}

然后我们可以添加一些具有不同用户输入的文档:

PUT multiple_datatypes/_doc/1
{
  "user_input": "hello"
}

PUT multiple_datatypes/_doc/2
{
  "user_input": "2017-02-12"
}

PUT multiple_datatypes/_doc/3
{
  "user_input": 5
}

当您搜索这些内容并具有范围和其他特定于类型的查询时,它们会按预期工作:

// Returns only document 2
GET multiple_datatypes/_search
{
  "query": {
    "range": {
      "user_input.date": {
        "gte": "2017-01-01"
      }
    }
  }
}

// Returns only document 3
GET multiple_datatypes/_search
{
  "query": {
    "range": {
      "user_input.numeric": {
        "lte": 9
      }
    }
  }
}

// Returns only document 1
GET multiple_datatypes/_search
{
  "query": {
    "term": {
      "user_input": {
        "value": "hello"
      }
    }
  }
}

我在博客文章here

中写道