ElasticSearch映射(一)

文章目录

  • ElasticSearch映射(一)
    • 动态映射
      • 动态字段映射
        • 日期检测
        • 关闭日期检测
        • 自定义日期检测格式
        • 数值检测
      • 动态模板
        • 验证动态模板
        • 在动态模板中映射运行时字段
        • `match_mapping_type`
        • `match`和`unmatch`
        • `path_match` 和`path_unmatch`
        • 模板变量
        • 动态模板示例
          • 结构化检索
          • 字符串的纯文本映射
          • 禁用`norms`
          • 时间序列
    • 明确映射
      • 创建带有明确映射的索引
      • 向现有映射添加字段
      • 查看索引的映射
      • 查看指定字段的映射

ElasticSearch映射(一)

映射是定义文档以及其包含的字段如果存储和索引的过程。

每个文档中的字段集合都有他们自己的数据类型。当你在映射数据的时候,你需要创建一个包含与文档相关的字段列表的映射定义。一个数据映射定义也可以包含元数据字段,例如_source字段,用于自定义处理文档相关的元数据。

你可以使用动态映射后者明确的映射来定义你的数据。每种方式都有他自己独特的好处。明确定义映你可以在字段上不使用默认值,或者你可以更好的控制创建哪些字段。然后你也可以让ElasticSearch来动态添加字段。

动态映射

动态字段映射

当ElasticSearch检测文档中出现了一个新的字段,它将会动态的为这个字段映射默认的数据类型。dynamic参数控制着这样的行为。

你可以通过设置dynamic参数的true或者runtime来明确的告诉ElasticSearch基于传入的文档来动态的创建字段。当动态字段映射开启的时候,ElasticSearch根据以下表格中的规则来决定怎么对每个字段进行映射数据类型。

JSON data type "dynamic":"true" "dynamic":"runtime"
null 不添加字段 不添加字段
true or false boolean boolean
double float double
integer long long
object1 object object
array 取决于数组中的第一个非空值 取决于数组中的第一个非空值
string that passes date detection date date
string that passes numeric detection float or long double or long
string that doesn’t pass date detection or numeric detection text with a .keyword sub-field keyword

你也可以在文档和对象级别关闭动态映射,设置dynamicfalse来忽略新的字段。如果ElasticSearch遇到新的字段,则strict拒绝这个文档。

提示:可以使用update mapping API来动态设置已经存在的字段

你可以动态的自定义日期检测和数值检测的字段映射规则,要自定义适用于其他动态字段,您可以使用dynamic templdate

日期检测

如果date_detection开启了(默认值),新的string字段会被检查它的内容是否与dynamic_date_formats中指定的任何日期格式相匹配,如果匹配,将添加相应格式的日期字段。

dynamic_date_formats的默认值为:

[ "strict_date_optional_time","yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z"]

例如:

curl -X PUT "localhost:9200/my-index-000001/_doc/1?pretty" -H 'Content-Type: application/json' -d'
{
  "create_date": "2015/09/02"
}'
curl -X GET "localhost:9200/my-index-000001/_mapping?pretty"
关闭日期检测

通过设置date_detectionfalse可以关闭日期检测:

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "date_detection": false
  }
}'
curl -X PUT "localhost:9200/my-index-000001/_doc/1?pretty" -H 'Content-Type: application/json' -d'
{
  "create": "2015/09/02"
}'
自定义日期检测格式

或者,dynamci_date_formats支持在你自己的date fomarts中自定义日期检测格式:

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "dynamic_date_formats": ["MM/dd/yyyy"]
  }
}'
curl -X PUT "localhost:9200/my-index-000001/_doc/1?pretty" -H 'Content-Type: application/json' -d'
{
  "create_date": "09/25/2015"
}'
数值检测

虽然 JSON 支持原生浮点和整数数据类型,但某些应用程序或语言有时可能会将数字呈现为字符串。通常正确的解决方案是显式映射这些字段,所以可以启用数字检测(默认情况下禁用)以自动执行此操作:

PUT my-index-000001
{
  "mappings": {
    "numeric_detection": true
  }
}
PUT my-index-000001/_doc/1{  "my_float":   "1.0",   "my_integer": "1" }

动态模板

动态模板可以在默认字段映射规则之外更好的控制ElasticSearch如果映射你的数字段。你可以设置动态字段映射参数为true或者runtime来开启动态字段映射。你也可以使用动态模板来自定义映射,动态模板映射基于匹配条件应用于动态添加的字段

  • match_mapping_type:对ElasticSearch检测到的数据类型进行操作。
  • matchunmatch:使用模式匹配来匹配字段名称
  • path_mathcpath_unmatch:对完整路径上的所有字段进行操作。
  • 如果动态模板没有定义match_mapping_type、match、unmatch、path_mathc、path_unmatch任何一个,它将不会匹配任何字段,您仍然可以在大批量请求的dynamic_template部分按名称引用模板。

使用映射规范中的{name}{dynamic_type}模板变量作为占位符

提示:动态值字段映射只有当一个字段值包含有效值(not null或者空数组)才会被增加。如果not_valuedynamic_tamplate中被使用,它只会在第一个具有该字段具体值的文档被索引后被应用

动态模板被命名为一个对象数组:

 "dynamic_templates": [    {      "my_template_name": {         ... match conditions ...         "mapping": { ... }       }    },    ...  ]
验证动态模板

如果提供的映射包含无效的映射片段,将会返回验证错误。发生在索引时或者大多数情况下动态索引被更新的时候会验证动态索引模板。提供无效的映射片段时可能导致更新或者验证动态模板失败:

  • 如果动态模板中没有配置match_mapping_type,但是模板对至少一种预定义的映射片段有效,则映射片段被视为有效。然而如果与动态模板匹配的的字段被索引为不同的类型,则在索引时返回验证错误。例如没有配置match_mapping_type的动态模板字符串类型是有效的,但是如果动态模板匹配到的字段为索引为Long,则在索引的时候会返回异常。建议在索引片段上将match_mapping_type设置为预期的JSON类型或者配置成想要的类型。
  • 如果{name}占位符被使用在映射片段中,当更新动态索引模板的时候会跳过验证,这是因为在这个时候字段名字还未知。验证发生在索引时候模板被应用的时候。

模板按顺序进行处理—第一个匹配到的模板获胜。当通过update mapping API来put一个新的动态模板,已存在的模板将会被覆盖。这允许动态模板在最初添加后重新排序或删除。

在动态模板中映射运行时字段

如果希望ElasticSearch将某种类型的新字段映射为运行时字段,需要在索引映射中设置"dynamic":"runtime"。这些字段不会加入索引中,在查询中从_source字段中加载。

或者你可以使用默认的动态模板规则,并创建动态模板将特定的字段映射为运行时字段。在你的索引映射中设置"dynamic":"true",然后创建一个动态模板将特定的类型的新字段映射成运行是字段。

假设您有数据其中每个字段都是以_ip开头。基于动态映射,ElasticSearch会将检测到的字符串映射为浮点数或者长整数。但是你可以创建一个动态模板,将新字符串映射为ip类型的运行时字段。

根据请求定义一个名字为string_as_ip的动态模板。当ElasticSearch检测一个新的string类型的新字段匹配ip*模式,它将这些字段映射成ip类型的运行时字段。因为ip字段没有被动态的映射,因此您可以将此模板与 "dynamic":"true""dynamic":"runtime" 一起使用:

curl -X PUT "localhost:9200/my-index-000001/?pretty" -H 'Content-Type: application/json' -d'{  "mappings": {    "dynamic_templates": [      {        "strings_as_ip": {          "match_mapping_type": "string",          "match": "ip*",          "runtime": {            "type": "ip"          }        }      }    ]  }}'
match_mapping_type

match_mapping_type是有JSON解析器检测的数据类型。因为JSON解析器不区分long、integer或者double、float,他总是选择最宽泛的数据类型,例如long作为整数,double作为浮点数。

ElasticSearch自动检测以下数据类型:

JSON data type "dynamic":"true" "dynamic":"runtime"
null No field added No field added
true or false boolean boolean
double float double
integer long long
object1 object object
array Depends on the first non-null value in the array Depends on the first non-null value in the array
string that passes date detection date date
string that passes numeric detection float or long double or long
string that doesn’t pass date detection or numeric detection text with a .keyword sub-field keyword

使用(*)可以匹配任意数据类型

例如,我们希望所有的integer字段映射为integer而不是long,所有的string类型映射为textkeyword类型,我们可以使用以下动态模板:

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'{  "mappings": {    "dynamic_templates": [      {        "integers": {          "match_mapping_type": "long",          "mapping": {            "type": "integer"          }        }      },      {        "strings": {          "match_mapping_type": "string",          "mapping": {            "type": "text",            "fields": {              "raw": {                "type":  "keyword",                "ignore_above": 256              }            }          }        }      }    ]  }}'
curl -X PUT "localhost:9200/my-index-000001/_doc/1?pretty" -H 'Content-Type: application/json' -d'{  "my_integer": 5,   "my_string": "Some string" }'
matchunmatch

match参数在字段名字上进行模式匹配,而unmatch用模式匹配去排除match匹配到的字段名称。

match_pattern 参数调整 match 参数的行为以支持完整的 Java 正则表达式匹配字段名称而不是简单的通配符。例如:

"match_pattern": "regex","match": "^profit_\d+$"

以下示例匹配所有以_long开头的string类型的字段(_text结尾的字符串字段除外),并将他们映射为long类型的字段:

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'{  "mappings": {    "dynamic_templates": [      {        "longs_as_strings": {          "match_mapping_type": "string",          "match":   "long_*",          "unmatch": "*_text",          "mapping": {            "type": "long"          }        }      }    ]  }}'
curl -X PUT "localhost:9200/my-index-000001/_doc/1?pretty" -H 'Content-Type: application/json' -d'{  "long_num": "5",   "long_text": "foo" }'
path_matchpath_unmatch

path_unmatch 参数的工作方式与 matchunmatch 相同,但对字段的完整虚线路径进行操作,而不仅仅是最终名称,例如some_object.*.some_field

此示例将 name 对象中任何字段的值复制到顶级 full_name 字段,middle段除外:

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'{  "mappings": {    "dynamic_templates": [      {        "full_name": {          "path_match":   "name.*",          "path_unmatch": "*.middle",          "mapping": {            "type":       "text",            "copy_to":    "full_name"          }        }      }    ]  }}'
curl -X PUT "localhost:9200/my-index-000001/_doc/1?pretty" -H 'Content-Type: application/json' -d'{  "name": {    "first":  "John",    "middle": "Winston",    "last":   "Lennon"  }}'

请注意,path_matchpath_unmatch 参数除了叶字段外还匹配对象路径。例如,索引以下文档将导致错误,因为 path_match 设置也匹配对象字段 name.title,它不能映射为文本:

curl -X PUT "localhost:9200/my-index-000001/_doc/2?pretty" -H 'Content-Type: application/json' -d'{  "name": {    "first":  "Paul",    "last":   "McCartney",    "title": {      "value": "Sir",      "category": "order of chivalry"    }  }}'
模板变量

在映射中{name}{dynamic_type}占位符替换为字段名称和检测到的动态类型。以下示例设置所有字符串字段使用与字段名称一样的analyzer分析器,为所有不是字符串的字段关闭doc_values

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'{  "mappings": {    "dynamic_templates": [      {        "named_analyzers": {          "match_mapping_type": "string",          "match": "*",          "mapping": {            "type": "text",            "analyzer": "{name}"          }        }      },      {        "no_doc_values": {          "match_mapping_type":"*",          "mapping": {            "type": "{dynamic_type}",            "doc_values": false          }        }      }    ]  }}'
curl -X PUT "localhost:9200/my-index-000001/_doc/1?pretty" -H 'Content-Type: application/json' -d'{  "english": "Some English text",   "count":   5 }'
动态模板示例
结构化检索

如果你设置dynamictrue,ElasticSearch会将字符串字段映射成带有keywordtext类型的文本字段。如果你只索引结构化的内容而不对全文索引感兴趣,您可以让ElasticSearch将您的字段仅映射成keyword字段。如果这样的话,那么您必须搜索这些字段的精确值:

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'{  "mappings": {    "dynamic_templates": [      {        "strings_as_keywords": {          "match_mapping_type": "string",          "mapping": {            "type": "keyword"          }        }      }    ]  }}'
字符串的纯文本映射

与上个示例完全相反,如果只关心在字符串的字段上进行全文检索并且没有计划运行聚合、排序和精确检索,你需要告诉ElasticSearch将字符串映射为text文本:

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'{  "mappings": {    "dynamic_templates": [      {        "strings_as_text": {          "match_mapping_type": "string",          "mapping": {            "type": "text"          }        }      }    ]  }}'

或者。你可以创建一个动态映射模板在运行时来映射字符串字段为keyword类型。当ElasticSearch检测到有新的string字段时,这些字段将被创建为keyword类型的运行时字段。

尽管这些string字段不会被索引,但是他们的值存储在_source内部字段中,你可以使用检索、聚合、排序、过滤等请求。

例如以下示例,根据请求创建一个动态模板将string类型的字段映射成keyword类型的运行时字段,尽管runtime值定义为空,但是新的string字段会根据动态映射规则映射成keyword类型的运行时字段。未通过日期检测和数值检测的string类型的字段都会被自动映射成keyword类型。

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'{  "mappings": {    "dynamic_templates": [      {        "strings_as_keywords": {          "match_mapping_type": "string",          "runtime": {}        }      }    ]  }}'

你索引的一个简单的文档:

curl -X PUT "localhost:9200/my-index-000001/_doc/1?pretty" -H 'Content-Type: application/json' -d'{  "english": "Some English text",  "count":   5}'

查看映射时,您会看到 english 字段是关键字类型的运行时字段:

{  "my-index-000001" : {    "mappings" : {      "dynamic_templates" : [        {          "strings_as_keywords" : {            "match_mapping_type" : "string",            "runtime" : { }          }        }      ],      "runtime" : {        "english" : {          "type" : "keyword"        }      },      "properties" : {        "count" : {          "type" : "long"        }      }    }  }}
禁用norms

norms是在索引时评分因素,如果你不关心评分,并且从来不按评分排序来检索文档,你可以禁用评分,这样可以节省一些空间。

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'{  "mappings": {    "dynamic_templates": [      {        "strings_as_keywords": {          "match_mapping_type": "string",          "mapping": {            "type": "text",            "norms": false,            "fields": {              "keyword": {                "type": "keyword",                "ignore_above": 256              }            }          }        }      }    ]  }}'

以上将string类型的字段映射为text类型的字段,文本检索可以利用字段进行检索,聚合和排序可以利用field.keyword上进行。

时间序列

在使用Elasticsearch进行时间序列分析时,通常会有许多数值字段,您通常会对这些字段进行聚合,但不会对它们进行过滤。在这种情况下,你可以禁用这些字段的索引,以节省磁盘空间,也可能获得一些索引速度:

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'{  "mappings": {    "dynamic_templates": [      {        "unindexed_longs": {          "match_mapping_type": "long",          "mapping": {            "type": "long",            "index": false          }        }      },      {        "unindexed_doubles": {          "match_mapping_type": "double",          "mapping": {            "type": "float",             "index": false          }        }      }    ]  }}'

与默认的动态映射规则一样,双精度数被映射为浮点数,这通常足够准确,但需要一半的磁盘空间。

明确映射

您对数据的了解比 Elasticsearch要多,因此虽然动态映射对于开始很有用,但在某些时候您会想要指定自己的显式映射。

您可以在创建索引或者向已存在的索引上添加新字段时创建字段映射。

创建带有明确映射的索引

您可以使用 create index API 通过显式映射创建新索引。

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'{  "mappings": {    "properties": {      "age":    { "type": "integer" },        "email":  { "type": "keyword"  },       "name":   { "type": "text"  }         }  }}'

向现有映射添加字段

您可以使用更新映射 API 向现有索引添加一个或多个新字段。

以下示例添加了员工 ID,这是一个索引映射参数值为 false 的关键字字段。这意味着员工 ID 字段的值已存储但未编入索引或可用于搜索。

curl -X PUT "localhost:9200/my-index-000001/_mapping?pretty" -H 'Content-Type: application/json' -d'{  "properties": {    "employee-id": {      "type": "keyword",      "index": false    }  }}'

查看索引的映射

你可以使用get mappingAPI获取存在索引的映射

curl -X GET "localhost:9200/my-index-000001/_mapping?pretty"

API响应

{  "my-index-000001" : {    "mappings" : {      "properties" : {        "age" : {          "type" : "integer"        },        "email" : {          "type" : "keyword"        },        "employee-id" : {          "type" : "keyword",          "index" : false        },        "name" : {          "type" : "text"        }      }    }  }}

查看指定字段的映射

如果你向单独查看一个或者更多字段的映射,你可以使用get mappingAPI来查看。

curl -X GET "localhost:9200/my-index-000001/_mapping/field/employee-id?pretty"

响应

{  "my-index-000001" : {    "mappings" : {      "employee-id" : {        "full_name" : "employee-id",        "mapping" : {          "employee-id" : {            "type" : "keyword",            "index" : false          }        }      }    }  }}

你可能感兴趣的:(elasticsearch,elasticsearch)