映射参数
edit映射参数
edit以下页面提供了对字段映射所使用的各种映射参数的详细解释:
以下映射参数适用于部分或所有字段数据类型:
分析器
edit只有 text 字段支持 analyzer 映射参数。
参数 analyzer 指定了用于在索引或搜索 text 字段时进行 分析器 的 文本分析。
除非使用 search_analyzer 映射参数覆盖,否则此分析器将用于 索引和搜索分析。请参阅 指定分析器。
我们建议在生产环境中使用之前测试分析器。请参阅 测试分析器。
在现有字段上使用更新映射API时,analyzer设置不能被更新。
search_quote_analyzer
editThe search_quote_analyzer 设置允许您为短语指定一个分析器,这在处理禁用短语查询的停用词时特别有用。
要禁用短语的字段停用词,需要使用三个分析器设置的字段:
-
用于索引所有术语(包括停用词)的
analyzer设置 -
用于非短语查询的
search_analyzer设置,将移除停用词 -
用于短语查询的
search_quote_analyzer设置,不会移除停用词
PUT my-index-000001
{
"settings":{
"analysis":{
"analyzer":{
"my_analyzer":{
"type":"custom",
"tokenizer":"standard",
"filter":[
"lowercase"
]
},
"my_stop_analyzer":{
"type":"custom",
"tokenizer":"standard",
"filter":[
"lowercase",
"english_stop"
]
}
},
"filter":{
"english_stop":{
"type":"stop",
"stopwords":"_english_"
}
}
}
},
"mappings":{
"properties":{
"title": {
"type":"text",
"analyzer":"my_analyzer",
"search_analyzer":"my_stop_analyzer",
"search_quote_analyzer":"my_analyzer"
}
}
}
}
PUT my-index-000001/_doc/1
{
"title":"The Quick Brown Fox"
}
PUT my-index-000001/_doc/2
{
"title":"A Quick Brown Fox"
}
GET my-index-000001/_search
{
"query":{
"query_string":{
"query":"\"the quick brown fox\""
}
}
}
可以使用更新映射API在现有字段上更新search_quote_analyzer设置。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
由于查询被引号包围,因此被检测为短语查询,因此 |
coerce
edit数据并不总是干净的。根据数据的生成方式,一个数字可能在JSON主体中被渲染为真正的JSON数字,例如5,但它也可能被渲染为字符串,例如"5"。或者,一个应该是整数的数字可能会被渲染为浮点数,例如5.0,甚至"5.0"。
强制转换尝试清理脏值以适应字段的数据类型。 例如:
- 字符串将被强制转换为数字。
- 浮点数将被截断为整数值。
例如:
PUT my-index-000001
{
"mappings": {
"properties": {
"number_one": {
"type": "integer"
},
"number_two": {
"type": "integer",
"coerce": false
}
}
}
}
PUT my-index-000001/_doc/1
{
"number_one": "10"
}
PUT my-index-000001/_doc/2
{
"number_two": "10"
}
可以使用更新映射API更新现有字段上的coerce设置值。
索引级默认值
edit可以在索引级别设置 index.mapping.coerce 设置,以全局禁用所有映射类型的强制转换:
copy_to
edit参数 copy_to 允许你将多个字段的值复制到一个组字段中,然后可以将其作为一个单一字段进行查询。
如果你经常搜索多个字段,可以通过使用copy_to来减少搜索字段,从而提高搜索速度。请参阅尽量减少搜索字段。
例如,可以将 first_name 和 last_name 字段复制到 full_name 字段,如下所示:
PUT my-index-000001
{
"mappings": {
"properties": {
"first_name": {
"type": "text",
"copy_to": "full_name"
},
"last_name": {
"type": "text",
"copy_to": "full_name"
},
"full_name": {
"type": "text"
}
}
}
}
PUT my-index-000001/_doc/1
{
"first_name": "John",
"last_name": "Smith"
}
GET my-index-000001/_search
{
"query": {
"match": {
"full_name": {
"query": "John Smith",
"operator": "and"
}
}
}
}
|
将 |
|
|
字段 |
一些重要点:
- 复制的是字段值,而不是术语(术语是分析过程的结果)。
-
原始的
_source字段不会被修改以显示复制的值。 -
可以将相同的值复制到多个字段,使用
"copy_to": [ "field_1", "field_2" ] -
您不能使用中间字段进行递归复制。 以下配置不会将数据从
field_1复制到field_3:PUT bad_example_index { "mappings": { "properties": { "field_1": { "type": "text", "copy_to": "field_2" }, "field_2": { "type": "text", "copy_to": "field_3" }, "field_3": { "type": "text" } } } }相反,从源字段复制到多个字段:
PUT good_example_index { "mappings": { "properties": { "field_1": { "type": "text", "copy_to": ["field_2", "field_3"] }, "field_2": { "type": "text" }, "field_3": { "type": "text" } } } }
copy_to 不支持值为对象形式的字段类型,例如 date_range。
动态映射
edit使用copy_to与动态映射时,请考虑以下几点:
doc_values
edit大多数字段默认是索引的,这使得它们可以被搜索。倒排索引允许查询在唯一的排序术语列表中查找搜索术语,并立即访问包含该术语的文档列表。
排序、聚合和在脚本中访问字段值需要不同的数据访问模式。我们需要能够查找文档并找到其在某个字段中的术语,而不是查找术语并找到文档。
Doc values 是在文档索引时构建的磁盘数据结构,使得这种数据访问模式成为可能。它们存储与 _source 相同的值,但以面向列的方式存储,这种方式对于排序和聚合更加高效。Doc values 几乎支持所有字段类型,但 值得注意的是,text 和 annotated_text 字段除外。
仅文档值字段
edit数字类型, 日期类型, 布尔类型, IP类型, 地理点类型 和 关键词类型 也可以在它们未被索引但仅启用了文档值时进行查询。 在文档值上的查询性能比在索引结构上慢得多,但对于那些仅偶尔查询且查询性能不那么重要的字段来说,它在磁盘使用和查询性能之间提供了一个有趣的权衡。这使得仅文档值字段非常适合那些不期望通常用于过滤的字段,例如指标数据上的仪表或计数器。
仅文档值字段可以按如下方式配置:
dynamic
edit当你索引一个包含新字段的文档时,Elasticsearch 动态地添加该字段到文档或文档内的嵌套对象中。以下文档添加了字符串字段 username,对象字段 name,以及在 name 对象下的两个字符串字段:
PUT my-index-000001/_doc/1
{
"username": "johnsmith",
"name": {
"first": "John",
"last": "Smith"
}
}
GET my-index-000001/_mapping
以下文档添加了两个字符串字段:email 和 name.middle:
PUT my-index-000001/_doc/2
{
"username": "marywhite",
"email": "mary@white.com",
"name": {
"first": "Mary",
"middle": "Alice",
"last": "White"
}
}
GET my-index-000001/_mapping
在内部对象上设置dynamic
edit内部对象 继承自其父对象的 dynamic 设置。在以下示例中,动态映射在类型级别被禁用,因此不会动态添加新的顶级字段。
然而,user.social_networks 对象启用了动态映射,因此您可以向这个内部对象添加字段。
用于动态的参数
edit参数 dynamic 控制是否动态添加新字段,并接受以下参数:
|
|
新字段被添加到映射中(默认)。 |
|
|
新字段作为 运行时字段 添加到映射中。
这些字段未被索引,并且在查询时从 |
|
|
新字段将被忽略。这些字段将不会被索引或搜索,但仍会出现在返回的命中结果的 |
|
|
如果检测到新字段,则会抛出异常并且文档被拒绝。新字段必须显式添加到映射中。 |
达到字段限制时的行为
edit将 dynamic 设置为 true 或 runtime 只会添加动态字段,直到达到 index.mapping.total_fields.limit。
默认情况下,超出字段限制的文档索引请求将会失败,
除非将 index.mapping.total_fields.ignore_dynamic_beyond_limit 设置为 true。
在这种情况下,被忽略的字段将被添加到 _ignored 元数据字段中。
eager_global_ordinals
edit什么是全局序数?
edit为了支持需要基于每个文档查找字段值的聚合和其他操作,Elasticsearch 使用了一种称为 doc values 的数据结构。基于词项的字段类型(如 keyword)使用序号映射来存储其 doc values,以获得更紧凑的表示形式。这种映射通过根据词项的字典顺序为其分配一个递增的整数或 序号 来工作。该字段的 doc values 仅存储每个文档的序号,而不是原始词项,并使用单独的查找结构在序号和词项之间进行转换。
在聚合过程中使用时,序号可以大大提高性能。例如,terms 聚合仅依赖序号在分片级别将文档收集到桶中,然后在跨分片合并结果时将序号转换回其原始术语值。
每个索引段定义了自己的序号映射,但聚合操作会收集整个分片的数据。因此,为了能够在分片级别的操作(如聚合)中使用序号,Elasticsearch 创建了一个称为全局序号的统一映射。全局序号映射建立在段序号之上,通过维护一个从全局序号到每个段本地序号的映射来工作。
如果搜索包含以下任何组件,则使用全局序号:
-
对
keyword、ip和flattened字段进行某些桶聚合。这包括如上所述的terms聚合,以及composite、diversified_sampler和significant_terms。 -
对需要启用
fielddata的text字段进行桶聚合。 -
对来自
join字段的父文档和子文档的操作,包括has_child查询和parent聚合。
加载全局序数
edit全局序数映射必须在搜索过程中使用序数之前构建。默认情况下,映射在第一次需要全局序数时在搜索期间加载。如果你正在优化索引速度,这是正确的方法,但如果搜索性能是优先考虑的,建议在将用于聚合的字段上预先加载全局序数:
PUT my-index-000001/_mapping
{
"properties": {
"tags": {
"type": "keyword",
"eager_global_ordinals": true
}
}
}
当启用 eager_global_ordinals 时,全局序号在分片 刷新 时构建——Elasticsearch 总是在暴露索引内容的变化之前加载它们。这将从搜索时构建全局序号的成本转移到索引时。Elasticsearch 在创建分片的新副本时也会急切地构建全局序号,例如在增加副本数量或将分片重新定位到新节点时。
可以通过更新eager_global_ordinals设置随时禁用预加载:
PUT my-index-000001/_mapping
{
"properties": {
"tags": {
"type": "keyword",
"eager_global_ordinals": false
}
}
}
避免全局序号加载
edit通常,全局序数在加载时间和内存使用方面不会带来很大的开销。然而,在具有大分片的索引上,或者如果字段包含大量唯一项值,加载全局序数可能会很昂贵。因为全局序数为分片上的所有段提供了一个统一的映射,所以当一个新的段变得可见时,它们也需要完全重建。
在某些情况下,可以完全避免全局序数加载:
-
terms、sampler和significant_terms聚合支持一个参数execution_hint用于控制如何收集桶。它默认设置为global_ordinals, 但可以设置为map以直接使用术语值。 - 如果一个分片已经被 强制合并 到一个单一 段,那么它的段序数已经是分片的 全局 序数。在这种情况下,Elasticsearch 不需要构建全局序数映射, 使用全局序数不会产生额外的开销。请注意,出于性能原因,您应该仅对不再写入的索引进行强制合并。
启用
editElasticsearch 会尝试索引你提供的所有字段,但有时你只想存储字段而不对其进行索引。例如,想象一下你正在使用 Elasticsearch 作为 web 会话存储。你可能希望索引会话 ID 和最后更新时间,但你不需要对会话数据本身进行查询或运行聚合。
The enabled setting, which can be applied only to the top-level mapping
definition and to object fields, causes Elasticsearch to skip
parsing of the contents of the field entirely. The JSON can still be retrieved
from the _source field, but it is not searchable or
stored in any other way:
PUT my-index-000001
{
"mappings": {
"properties": {
"user_id": {
"type": "keyword"
},
"last_updated": {
"type": "date"
},
"session_data": {
"type": "object",
"enabled": false
}
}
}
}
PUT my-index-000001/_doc/session_1
{
"user_id": "kimchy",
"session_data": {
"arbitrary_object": {
"some_array": [ "foo", "bar", { "baz": 2 } ]
}
},
"last_updated": "2015-12-06T18:20:22"
}
PUT my-index-000001/_doc/session_2
{
"user_id": "jpountz",
"session_data": "none",
"last_updated": "2015-12-06T18:22:13"
}
整个映射也可以被禁用,在这种情况下,文档存储在_source字段中,这意味着它可以被检索,但其内容不会以任何方式被索引:
PUT my-index-000001
{
"mappings": {
"enabled": false
}
}
PUT my-index-000001/_doc/session_1
{
"user_id": "kimchy",
"session_data": {
"arbitrary_object": {
"some_array": [ "foo", "bar", { "baz": 2 } ]
}
},
"last_updated": "2015-12-06T18:20:22"
}
GET my-index-000001/_doc/session_1
GET my-index-000001/_mapping
现有字段的enabled设置和顶级映射定义无法更新。
请注意,由于 Elasticsearch 完全跳过解析字段内容,因此可以将非对象数据添加到已禁用的字段中:
格式
edit在JSON文档中,日期以字符串形式表示。Elasticsearch使用一组预配置的格式来识别并解析这些字符串,将其转换为表示自纪元以来的毫秒数的UTC长值。
除了内置格式,您还可以使用熟悉的
yyyy/MM/dd语法指定自己的
自定义格式。
PUT my-index-000001
{
"mappings": {
"properties": {
"date": {
"type": "date",
"format": "yyyy-MM-dd"
}
}
}
}
许多支持日期值的API也支持日期数学表达式,例如now-1m/d — 当前时间,减去一个月,向下舍入到最近的一天。
自定义日期格式
edit完全可定制的日期格式。这些格式的语法在 DateTimeFormatter文档中进行了解释。
请注意,尽管内置的周日期格式使用ISO定义的周年,但使用Y、W或w字段说明符的自定义格式化程序使用JDK区域设置定义的周年。这可能导致内置格式和自定义格式之间的周日期值不同。
内置格式
edit以下大多数格式都有一个严格的伴随格式,这意味着年、月和日的部分必须分别使用4位、2位和2位数字,必要时可以前置零。例如,像5/11/1这样的日期将被视为无效,需要重写为2005/11/01才能被日期解析器接受。
要使用它们,您需要在日期格式的名称前加上strict_,例如使用strict_date_optional_time而不是date_optional_time。
这些严格的日期格式在动态映射日期字段时特别有用,以确保不会意外地将无关的字符串映射为日期。
以下表格列出了所有支持的默认ISO格式:
-
epoch_millis -
一个用于自纪元以来的毫秒数的格式化器。请注意,此时间戳受限于Java
Long.MIN_VALUE和Long.MAX_VALUE的限制。 -
epoch_second -
一个用于自纪元以来的秒数的格式化器。请注意,这个时间戳受到Java
Long.MIN_VALUE和Long. MAX_VALUE除以1000(每秒的毫秒数)的限制。 -
date_optional_timeorstrict_date_optional_time -
一个通用的ISO日期时间解析器,其中日期必须至少包含年份,时间(由
T分隔)是可选的。 示例:yyyy-MM-dd'T'HH:mm:ss.SSSZ或yyyy-MM-dd。注意:当使用 `date_optional_time` 时,解析是宽松的,并且会尝试将数字解析为年份(例如 `292278994` 将被解析为年份)。当与像 `epoch_second` 和 `epoch_millis` 这样的数字格式配对时,这可能会导致意外的结果。建议在与数字格式配对时使用 `strict_date_optional_time`。
-
strict_date_optional_time_nanos -
一个通用的ISO日期时间解析器,其中日期必须至少包含年份,时间(以
T分隔)是可选的。秒的小数部分具有纳秒分辨率。 示例:yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ或yyyy-MM-dd。 -
basic_date -
一个基本的格式化器,用于显示四位数的年份、两位数的月份和两位数的日期:
yyyyMMdd。 -
basic_date_time -
一个基本的格式化器,将基本日期和时间组合在一起,用T分隔:
yyyyMMdd'T'HHmmss.SSSZ。 -
basic_date_time_no_millis -
一个基本的格式化器,结合了不带毫秒的基本日期和时间,由T分隔:
yyyyMMdd'T'HHmmssZ。 -
basic_ordinal_date -
一个用于完整序数日期的格式化器,使用四位数的年份和三位数的dayOfYear:
yyyyDDD。 -
basic_ordinal_date_time -
一个用于完整序数日期和时间的格式化器,使用四位数的年和三位数的dayOfYear:
yyyyDDD'T'HHmmss.SSSZ。 -
basic_ordinal_date_time_no_millis -
一个用于完整序数日期和时间的格式化器,不包括毫秒,使用四位数年份和三位数的天数:
yyyyDDD'T'HHmmssZ。 -
basic_time -
一个用于表示一天中的两位小时数、小时的两位分钟数、分钟的两位秒数、三位毫秒数和时区偏移量的基本格式化器:
HHmmss.SSSZ。 -
basic_time_no_millis -
一天中的两位数小时,小时的两位数分钟,分钟的两位数秒,以及时区偏移的基本格式化器:
HHmmssZ。 -
basic_t_time -
一天中的两位数小时,小时的两位数分钟,
分钟的两位数秒,三位数毫秒,以及时间偏移量
前缀为T:
'T'HHmmss.SSSZ。 -
basic_t_time_no_millis -
一个用于表示一天中的两位小时数、小时中的两位分钟数、分钟中的两位秒数以及以T为前缀的时区偏移量的基本格式化器:
'T'HHmmssZ。 -
basic_week_dateorstrict_basic_week_date -
一个完整的日期基本格式化器,格式为四位数的周年份、两位数的周数和一位数的星期几:
xxxx'W'wwe。 -
basic_week_date_timeorstrict_basic_week_date_time -
一个基本的格式化器,结合了基本的周年度日期和时间,由T分隔:
xxxx'W'wwe'T'HHmmss.SSSZ。 -
basic_week_date_time_no_millisorstrict_basic_week_date_time_no_millis -
一个基本的格式化器,结合了基本的周年度日期和时间,不带毫秒,由T分隔:
xxxx'W'wwe'T'HHmmssZ。 -
dateorstrict_date -
一个用于显示完整日期的格式化器,格式为四位数的年份、两位数的月份和两位数的日期:
yyyy-MM-dd。 -
date_hourorstrict_date_hour -
一个结合了完整日期和两位数小时的格式化器:
yyyy-MM-dd'T'HH。 -
date_hour_minuteorstrict_date_hour_minute -
一个结合了完整日期、两位数的小时和两位数的分钟的格式化器:
yyyy-MM-dd'T'HH:mm。 -
date_hour_minute_secondorstrict_date_hour_minute_second -
一个结合了完整日期、两位数的小时、两位数的分钟和两位数的秒的格式化器:
yyyy-MM-dd'T'HH:mm:ss。 -
date_hour_minute_second_fractionorstrict_date_hour_minute_second_fraction -
一个格式化器,结合了完整的日期、两位数的小时、两位数的分钟、两位数的秒和三位数的秒的小数部分:
yyyy-MM-dd'T'HH:mm:ss.SSS。 -
date_hour_minute_second_millisorstrict_date_hour_minute_second_millis -
一个格式化器,结合了完整日期、两位数的小时、两位数的分钟、两位数的秒和三位数的秒的小数部分:
yyyy-MM-dd'T'HH:mm:ss.SSS。 -
date_timeorstrict_date_time -
一个结合了完整日期和时间的格式化器,由T分隔:
yyyy-MM-dd'T'HH:mm:ss.SSSZ。 -
date_time_no_millisorstrict_date_time_no_millis -
一个结合了不带毫秒的完整日期和时间的格式化器,由T分隔:
yyyy-MM-dd'T'HH:mm:ssZ。 -
hourorstrict_hour -
一天中的两位数小时格式化器:
HH -
hour_minuteorstrict_hour_minute -
一天中的两位数小时和小时的两位数分钟的格式化器:
HH:mm。 -
hour_minute_secondorstrict_hour_minute_second -
一天中的两位数小时,一小时的两位数分钟,以及一分钟中的两位数秒的格式化器:
HH:mm:ss。 -
hour_minute_second_fractionorstrict_hour_minute_second_fraction -
一天中的两位数小时,小时的两位数分钟,分钟的两位数秒,以及秒的三位数分数的格式化器:
HH:mm:ss.SSS。 -
hour_minute_second_millisorstrict_hour_minute_second_millis -
一天中的两位数小时,小时的两位数分钟,分钟的两位数秒,以及秒的三位数分数的格式化器:
HH:mm:ss.SSS。 -
ordinal_dateorstrict_ordinal_date -
一个用于完整序数日期的格式化器,使用四位数的年份和三位数的dayOfYear:
yyyy-DDD。 -
ordinal_date_timeorstrict_ordinal_date_time -
一个用于完整序数日期和时间的格式化器,使用四位数的年和三位数的dayOfYear:
yyyy-DDD'T'HH:mm:ss.SSSZ。 -
ordinal_date_time_no_millisorstrict_ordinal_date_time_no_millis -
一个用于完整序数日期和时间的格式化器,不包括毫秒,使用四位数年份和三位数的天数:
yyyy-DDD'T'HH:mm:ssZ。 -
timeorstrict_time -
一个用于表示两位数的小时、两位数的分钟、两位数的秒、三位数的秒的小数部分以及时区偏移的格式化器:
HH:mm:ss.SSSZ。 -
time_no_millisorstrict_time_no_millis -
一天中的两位数小时,小时的两位数分钟,分钟的两位数秒,以及时区偏移的格式化器:
HH:mm:ssZ。 -
t_timeorstrict_t_time -
一个用于表示两位数的小时、两位数的分钟、两位数的秒、三位数的秒的小数部分以及以T为前缀的时区偏移的格式化器:
'T'HH:mm:ss.SSSZ。 -
t_time_no_millisorstrict_t_time_no_millis -
一个用于表示两位数的小时、两位数的分钟、两位数的秒以及以T为前缀的时区偏移的格式化器:
'T'HH:mm:ssZ。 -
week_dateorstrict_week_date -
一个用于完整日期的格式化器,格式为四位数的周年份、两位数的周数和一位数的星期几:
YYYY-'W'ww-e。 这使用了ISO周日期定义。 -
week_date_timeorstrict_week_date_time -
一个结合了完整周年和时间的格式化器,由T分隔:
YYYY-'W'ww-e'T'HH:mm:ss.SSSZ。 这使用了ISO周日期定义。 -
week_date_time_no_millisorstrict_week_date_time_no_millis -
一个结合了完整周年和时间(不含毫秒)的格式化器,由T分隔:
YYYY-'W'ww-e'T'HH:mm:ssZ。 这使用了ISO周日期定义。 -
weekyearorstrict_weekyear -
一个用于四位数周年的格式化器:
YYYY。 这使用了ISO周日期定义。 -
weekyear_weekorstrict_weekyear_week -
一个用于四位数年份和两位数周数的格式化器:
YYYY-'W'ww。 这使用了ISO周日期定义。 -
weekyear_week_dayorstrict_weekyear_week_day -
一个用于四位数年份、两位数周数和一位数星期几的格式化器:
YYYY-'W'ww-e。 这使用了ISO周日期定义。 -
yearorstrict_year -
四位数年份的格式化器:
yyyy。 -
year_monthorstrict_year_month -
一个用于四位数年份和两位数月份的年份格式化器:
yyyy-MM。 -
year_month_dayorstrict_year_month_day -
一个用于四位数年份、两位数月份和两位数日期的格式化器:
yyyy-MM-dd。
ignore_above
edit长度超过 ignore_above 设置的字符串将不会被索引或存储。
对于字符串数组,ignore_above 将分别应用于每个数组元素,并且长度超过 ignore_above 的字符串元素将不会被索引或存储。
所有字符串/数组元素仍将出现在 _source 字段中,如果启用了后者,这是 Elasticsearch 中的默认设置。
PUT my-index-000001
{
"mappings": {
"properties": {
"message": {
"type": "keyword",
"ignore_above": 20
}
}
}
}
PUT my-index-000001/_doc/1
{
"message": "Syntax error"
}
PUT my-index-000001/_doc/2
{
"message": "Syntax error with some long stacktrace"
}
GET my-index-000001/_search
{
"aggs": {
"messages": {
"terms": {
"field": "message"
}
}
}
}
可以使用更新映射API在现有字段上更新ignore_above设置。
此选项对于防止Lucene的词元字节长度限制32766也很有用。
The value for ignore_above 是 字符计数,但 Lucene 计算字节数。如果你使用包含许多非 ASCII 字符的 UTF-8 文本,你可能希望将限制设置为 32766 / 4 = 8191,因为 UTF-8 字符最多可能占用 4 个字节。
index.mapping.ignore_above
edit设置 ignore_above 通常在字段级别使用,也可以通过 index.mapping.ignore_above 在索引级别应用。此设置允许您为索引中的所有适用字段定义最大字符串长度,包括 keyword、wildcard 以及 flattened 字段中的关键字值。任何超过此限制的值将在索引期间被忽略,并且不会被存储。
此索引范围的设置确保了对管理过长值的一致性方法。它的工作方式与字段级别的设置相同——如果字符串的长度超过指定限制,该字符串将不会被索引或存储。在处理数组时,每个元素会分别进行评估,只有超过限制的元素会被忽略。
PUT my-index-000001
{
"settings": {
"index.mapping.ignore_above": 256
}
}
在这个示例中,my-index-000001 中的所有适用字段将忽略任何超过 256 个字符的字符串。
您可以通过在字段映射中指定自定义的 ignore_above 值来覆盖此索引范围的设置。
就像字段级别的 ignore_above 一样,此设置仅影响索引和存储。如果启用了 _source,原始值仍然可以在 _source 字段中使用,这是 Elasticsearch 中的默认行为。
ignore_malformed
edit有时候你无法完全控制接收到的数据。一个用户可能会发送一个login字段,该字段是一个date,而另一个用户发送的login字段则是一个电子邮件地址。
尝试将错误的数据类型索引到字段中会默认抛出异常,并拒绝整个文档。如果将 ignore_malformed 参数设置为 true,则允许忽略该异常。格式错误的字段不会被索引,但文档中的其他字段会正常处理。
例如:
PUT my-index-000001
{
"mappings": {
"properties": {
"number_one": {
"type": "integer",
"ignore_malformed": true
},
"number_two": {
"type": "integer"
}
}
}
}
PUT my-index-000001/_doc/1
{
"text": "Some text value",
"number_one": "foo"
}
PUT my-index-000001/_doc/2
{
"text": "Some text value",
"number_two": "foo"
}
目前,ignore_malformed 设置由以下 映射类型 支持:
可以使用更新映射API更新现有字段上的ignore_malformed设置值。
索引级别默认值
edit可以在索引级别设置 index.mapping.ignore_malformed 设置,以全局忽略所有允许的映射类型中的格式错误内容。
不支持该设置的映射类型如果在索引级别设置,将会忽略它。
索引
edit选项index控制字段值是否被索引。它接受true或false,默认为true。
为字段建立索引会创建数据结构,使得该字段能够被高效查询。数字类型、日期类型、 布尔类型、IP类型、地理点类型以及 关键字类型在未索引但启用了文档值时也可以查询。 但这些字段的查询速度较慢,因为需要进行全索引扫描。所有其他字段均不可查询。
索引选项
edit参数 index_options 控制了为了搜索和突出显示目的而添加到倒排索引中的信息。只有基于词项的字段类型,如 text 和 keyword,支持此配置。
该参数接受以下值之一。每个值从前面的值中检索信息。例如,freqs 包含 docs;positions 包含 freqs 和 docs。
index_phrases
edit如果启用,双词组合(shingles)将被索引到一个单独的字段中。这使得精确短语查询(无偏差)能够更高效地运行,但代价是索引更大。请注意,当停用词未被移除时,此功能效果最佳,因为包含停用词的短语将不会使用辅助字段,而是回退到标准短语查询。接受 true 或 false(默认)。
index_prefixes
edit参数 index_prefixes 启用了术语前缀的索引,以加快前缀搜索的速度。它接受以下可选设置:
|
|
要索引的最小前缀长度。必须大于 0,默认值为 2。该值包含在内。 |
|
|
要索引的最大前缀长度。必须小于20,默认值为5。 该值是包含的。 |
此示例使用默认的前缀长度设置创建一个文本字段:
PUT my-index-000001
{
"mappings": {
"properties": {
"body_text": {
"type": "text",
"index_prefixes": { }
}
}
}
}
此示例使用自定义前缀长度设置:
PUT my-index-000001
{
"mappings": {
"properties": {
"full_name": {
"type": "text",
"index_prefixes": {
"min_chars" : 1,
"max_chars" : 10
}
}
}
}
}
元数据
edit附加到字段的元数据。此元数据对Elasticsearch是不透明的,它仅对在同一索引上工作的多个应用程序有用,以便共享关于字段的元信息,例如单位
PUT my-index-000001
{
"mappings": {
"properties": {
"latency": {
"type": "long",
"meta": {
"unit": "ms"
}
}
}
}
}
字段元数据最多允许5个条目,键的长度必须小于或等于20,并且值必须是字符串,其长度必须小于或等于50。
字段元数据可以通过提交映射更新来更新。更新后的元数据将覆盖现有字段的元数据。
字段元数据在对象或嵌套字段上不受支持。
Elastic 产品使用以下标准元数据条目来表示字段。您可以遵循这些相同的元数据约定,以获得更好的开箱即用体验。
- unit
-
与数值字段关联的单位:
"percent"、"byte"或一个 时间单位。默认情况下,字段没有单位。 仅对数值字段有效。百分比的约定是使用值1表示100%。 - metric_type
-
数值字段的指标类型:
"gauge"或"counter"。gauge 是一个可以随时间上升或下降的单值测量值,例如温度。counter 是一个仅上升的单值累积计数器,例如由 Web 服务器处理的请求数量,或者重置为 0(零)。默认情况下,字段不与任何指标类型关联。仅对数值字段有效。
字段
edit为了不同的目的,通常需要以不同的方式索引同一个字段。这就是多字段的目的。例如,一个字符串字段可以映射为文本字段用于全文搜索,并映射为关键词字段用于排序或聚合:
PUT my-index-000001
{
"mappings": {
"properties": {
"city": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
}
}
}
}
PUT my-index-000001/_doc/1
{
"city": "New York"
}
PUT my-index-000001/_doc/2
{
"city": "York"
}
GET my-index-000001/_search
{
"query": {
"match": {
"city": "york"
}
},
"sort": {
"city.raw": "asc"
},
"aggs": {
"Cities": {
"terms": {
"field": "city.raw"
}
}
}
}
您可以使用更新映射 API向现有字段添加多字段。
如果在添加多字段时索引(或数据流)中已包含文档,这些文档将不会包含新多字段的值。您可以使用通过查询更新API来填充新多字段。
多字段映射与父字段的映射完全分开。多字段不会从其父字段继承任何映射选项。多字段不会改变原始的 _source 字段。
使用多个分析器的多字段
edit多字段的另一个用例是为了更好地提高相关性,以不同的方式分析同一个字段。例如,我们可以使用standard 分析器将文本分解成单词,并再次使用english 分析器将单词词干化为它们的根形式:
PUT my-index-000001
{
"mappings": {
"properties": {
"text": {
"type": "text",
"fields": {
"english": {
"type": "text",
"analyzer": "english"
}
}
}
}
}
}
PUT my-index-000001/_doc/1
{ "text": "quick brown fox" }
PUT my-index-000001/_doc/2
{ "text": "quick brown foxes" }
GET my-index-000001/_search
{
"query": {
"multi_match": {
"query": "quick brown foxes",
"fields": [
"text",
"text.english"
],
"type": "most_fields"
}
}
}
|
The |
|
|
The |
|
|
索引两个文档,一个包含 |
|
|
查询 |
字段 text 在第一个文档中包含术语 fox,在第二个文档中包含 foxes。字段 text.english 在两个文档中都包含 fox,因为 foxes 被词干化为 fox。
查询字符串也会被standard分析器分析用于text字段,并且被english分析器分析用于text.english字段。词干化字段允许查询foxes也能匹配包含fox的文档。这使得我们能够匹配尽可能多的文档。通过同时查询未词干化的text字段,我们提高了精确匹配foxes的文档的相关性评分。
normalizer
edit字段 keyword 的 normalizer 属性类似于 analyzer,但它保证分析链生成单个标记。
在索引关键字之前以及通过查询解析器(如match查询或通过术语级查询(如term查询)搜索keyword字段时,都会应用normalizer。
一个简单的标准化器叫做 lowercase 随elasticsearch一起提供,可以使用。
自定义标准化器可以作为分析设置的一部分定义如下。
PUT index
{
"settings": {
"analysis": {
"normalizer": {
"my_normalizer": {
"type": "custom",
"char_filter": [],
"filter": ["lowercase", "asciifolding"]
}
}
}
},
"mappings": {
"properties": {
"foo": {
"type": "keyword",
"normalizer": "my_normalizer"
}
}
}
}
PUT index/_doc/1
{
"foo": "BÀR"
}
PUT index/_doc/2
{
"foo": "bar"
}
PUT index/_doc/3
{
"foo": "baz"
}
POST index/_refresh
GET index/_search
{
"query": {
"term": {
"foo": "BAR"
}
}
}
GET index/_search
{
"query": {
"match": {
"foo": "BAR"
}
}
}
上述查询匹配文档1和2,因为在索引和查询时,BÀR 被转换为 bar。
{
"took": $body.took,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped" : 0,
"failed": 0
},
"hits": {
"total" : {
"value": 2,
"relation": "eq"
},
"max_score": 0.4700036,
"hits": [
{
"_index": "index",
"_id": "1",
"_score": 0.4700036,
"_source": {
"foo": "BÀR"
}
},
{
"_index": "index",
"_id": "2",
"_score": 0.4700036,
"_source": {
"foo": "bar"
}
}
]
}
}
此外,关键字在索引之前被转换的事实也意味着聚合返回的是归一化值:
GET index/_search
{
"size": 0,
"aggs": {
"foo_terms": {
"terms": {
"field": "foo"
}
}
}
}
返回
{
"took": 43,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped" : 0,
"failed": 0
},
"hits": {
"total" : {
"value": 3,
"relation": "eq"
},
"max_score": null,
"hits": []
},
"aggregations": {
"foo_terms": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "bar",
"doc_count": 2
},
{
"key": "baz",
"doc_count": 1
}
]
}
}
}
norms
editNorms 存储各种归一化因子,这些因子在查询时用于计算文档相对于查询的得分。
尽管对于评分很有用,但规范也需要相当多的磁盘空间(通常在你的索引中,每个字段每个文档大约需要一个字节,即使文档没有这个特定字段)。因此,如果你不需要对特定字段进行评分,你应该禁用该字段的规范。特别是,这对于仅用于过滤或聚合的字段来说,是这种情况。
可以使用更新映射 API在现有字段上禁用规范。
可以使用更新映射 API来禁用规范(但事后不能重新启用),如下所示:
PUT my-index-000001/_mapping
{
"properties": {
"title": {
"type": "text",
"norms": false
}
}
}
规范不会立即被移除,而是会在你继续索引新文档时,随着旧段合并到新段中而被移除。任何对已经移除规范的字段进行评分计算的操作可能会返回不一致的结果,因为有些文档不再有规范,而其他文档可能仍然有规范。
null_value
edit一个null值不能被索引或搜索。当一个字段被设置为null时,
(或者是一个空数组或一个包含null值的数组),它将被视为该字段没有值。
参数 null_value 允许你用指定的值替换显式的 null 值,以便它可以被索引和搜索。例如:
PUT my-index-000001
{
"mappings": {
"properties": {
"status_code": {
"type": "keyword",
"null_value": "NULL"
}
}
}
}
PUT my-index-000001/_doc/1
{
"status_code": null
}
PUT my-index-000001/_doc/2
{
"status_code": []
}
GET my-index-000001/_search
{
"query": {
"term": {
"status_code": "NULL"
}
}
}
The null_value 需要与字段的数据类型相同。例如,一个 long 字段不能有一个字符串类型的 null_value。
The null_value 仅影响数据的索引方式,它不会修改 _source 文档。
position_increment_gap
edit分析文本字段会考虑词项的位置,以便能够支持邻近或短语查询。当索引具有多个值的文本字段时,会在这些值之间添加一个“假”间隙,以防止大多数短语查询跨值匹配。此间隙的大小通过position_increment_gap进行配置,默认值为100。
例如:
PUT my-index-000001/_doc/1
{
"names": [ "John Abraham", "Lincoln Smith"]
}
GET my-index-000001/_search
{
"query": {
"match_phrase": {
"names": {
"query": "Abraham Lincoln"
}
}
}
}
GET my-index-000001/_search
{
"query": {
"match_phrase": {
"names": {
"query": "Abraham Lincoln",
"slop": 101
}
}
}
}
|
这个短语查询没有匹配到我们的文档,这是完全预期的。 |
|
|
即使 |
可以在映射中指定position_increment_gap。例如:
属性
edit类型映射、对象字段和嵌套字段
包含子字段,称为属性。这些属性可以是任何
数据类型,包括对象和嵌套。可以添加属性:
下面是一个向映射类型、对象字段和嵌套字段添加属性的示例:
PUT my-index-000001
{
"mappings": {
"properties": {
"manager": {
"properties": {
"age": { "type": "integer" },
"name": { "type": "text" }
}
},
"employees": {
"type": "nested",
"properties": {
"age": { "type": "integer" },
"name": { "type": "text" }
}
}
}
}
}
PUT my-index-000001/_doc/1
{
"region": "US",
"manager": {
"name": "Alice White",
"age": 30
},
"employees": [
{
"name": "John Smith",
"age": 34
},
{
"name": "Peter Brown",
"age": 26
}
]
}
允许为同一索引中同名字段设置不同的 properties。可以使用 更新映射 API 向现有字段添加新属性。
点表示法
edit内部字段可以在查询、聚合等中使用点表示法进行引用:
GET my-index-000001/_search
{
"query": {
"match": {
"manager.name": "Alice White"
}
},
"aggs": {
"Employees": {
"nested": {
"path": "employees"
},
"aggs": {
"Employee Ages": {
"histogram": {
"field": "employees.age",
"interval": 5
}
}
}
}
}
}
必须指定内部字段的全路径。
搜索分析器
edit通常,在索引时和搜索时应该应用相同的分析器,以确保查询中的术语与倒排索引中的术语格式相同。
有时,在搜索时使用不同的分析器是有意义的,例如在使用 edge_ngram
分词器进行自动补全时,或者在使用搜索时同义词时。
默认情况下,查询将使用字段映射中定义的 analyzer,但可以使用 search_analyzer 设置进行覆盖:
PUT my-index-000001
{
"settings": {
"analysis": {
"filter": {
"autocomplete_filter": {
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 20
}
},
"analyzer": {
"autocomplete": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"autocomplete_filter"
]
}
}
}
},
"mappings": {
"properties": {
"text": {
"type": "text",
"analyzer": "autocomplete",
"search_analyzer": "standard"
}
}
}
}
PUT my-index-000001/_doc/1
{
"text": "Quick Brown Fox"
}
GET my-index-000001/_search
{
"query": {
"match": {
"text": {
"query": "Quick Br",
"operator": "and"
}
}
}
}
|
分析设置以定义自定义的 |
|
|
在索引时, |
|
|
此字段被索引为以下词项:[ |
|
|
查询搜索这两个词:[ |
请参阅索引时即搜即得以获取此示例的完整解释。
可以使用更新映射API更新现有字段上的search_analyzer设置。请注意,为此,需要在更新的字段定义中重复任何现有的“analyzer”设置和“type”。
相似性
editElasticsearch 允许您为每个字段配置一个文本评分算法或 相似性。similarity 设置提供了一种简单的方法来选择除默认 BM25 之外的文本相似性算法,例如 boolean。
仅支持基于文本的字段类型,如 text 和 keyword
支持此配置。
可以通过调整内置相似度的参数来配置自定义相似度。有关此专家选项的更多详细信息,请参阅相似度模块。
无需任何进一步配置即可直接使用的唯一相似性是:
-
BM25 - Okapi BM25算法。Elasticsearch和Lucene中默认使用的算法。
-
boolean - 一个简单的布尔相似度,用于不需要全文排序且分数仅基于查询词是否匹配的情况。布尔相似度为词项赋予的分数等于它们的查询提升值。
可以在首次创建字段时在字段级别设置相似度,如下所示:
存储
edit默认情况下,字段值会被索引以使其可搜索,但它们不会被存储。这意味着该字段可以被查询,但原始字段值无法被检索。
通常这并不重要。字段值已经是
_source 字段的一部分,默认情况下会存储该字段。如果你
只想检索单个字段或几个字段的值,而不是整个 _source,那么可以通过
源过滤来实现。
在某些情况下,存储一个字段是有意义的。例如,如果你有一个包含标题、日期和一个非常大的内容字段的文档,你可能希望只检索标题和日期,而不必从大的_source字段中提取这些字段:
PUT my-index-000001
{
"mappings": {
"properties": {
"title": {
"type": "text",
"store": true
},
"date": {
"type": "date",
"store": true
},
"content": {
"type": "text"
}
}
}
}
PUT my-index-000001/_doc/1
{
"title": "Some short title",
"date": "2015-01-01",
"content": "A very long content field..."
}
GET my-index-000001/_search
{
"stored_fields": [ "title", "date" ]
}
存储字段返回为数组
为了保持一致性,存储的字段总是以数组的形式返回,因为无法知道原始字段值是单个值、多个值还是空数组。
如果你需要原始值,你应该从_source字段中获取它。
子对象
edit在索引文档或更新映射时,Elasticsearch 接受包含点号的字段名称,这些名称会被扩展为其对应的对象结构。例如,字段 metrics.time.max 被映射为一个 max 叶子字段,其父对象为 time,而 time 又属于其父对象 metrics。
所述的默认行为在大多数场景下是合理的,但在某些情况下会导致问题,例如当字段 metrics.time 也包含一个值时,这在索引度量数据时很常见。如果一个文档同时包含 metrics.time.max 和 metrics.time 的值,则该文档会被拒绝,因为 time 需要同时作为叶子字段来保存值,并且作为对象来保存 max 子字段。
设置subobjects,该设置仅适用于顶级映射定义和object字段,禁用了对象持有进一步子对象的能力,并使得存储字段名称包含点和共享公共前缀的文档成为可能。从上面的例子来看,如果对象容器metrics的subobjects设置为false,它可以直接保存time和time.max的值,而不需要任何中间对象,因为字段名称中的点被保留。
PUT my-index-000001
{
"mappings": {
"properties": {
"metrics": {
"type": "object",
"subobjects": false,
"properties": {
"time": { "type": "long" },
"time.min": { "type": "long" },
"time.max": { "type": "long" }
}
}
}
}
}
PUT my-index-000001/_doc/metric_1
{
"metrics.time" : 100,
"metrics.time.min" : 10,
"metrics.time.max" : 900
}
PUT my-index-000001/_doc/metric_2
{
"metrics" : {
"time" : 100,
"time.min" : 10,
"time.max" : 900
}
}
GET my-index-000001/_mapping
{
"my-index-000001" : {
"mappings" : {
"properties" : {
"metrics" : {
"subobjects" : false,
"properties" : {
"time" : {
"type" : "long"
},
"time.min" : {
"type" : "long"
},
"time.max" : {
"type" : "long"
}
}
}
}
}
}
}
整个映射可能被配置为不支持子对象,在这种情况下,文档只能包含叶子子字段:
PUT my-index-000001
{
"mappings": {
"subobjects": false
}
}
PUT my-index-000001/_doc/metric_1
{
"time" : "100ms",
"time.min" : "10ms",
"time.max" : "900ms"
}
现有字段的子对象设置和顶级映射定义无法更新。
自动展平对象映射
edit通常建议使用带点的字段名称来定义配置了 subobjects: false 的对象的属性(如第一个示例所示)。然而,也可以在映射中将这些属性定义为子对象。在这种情况下,映射会在存储之前自动展平。这使得无需重写即可更容易地重用现有映射。
请注意,当某些映射参数设置在对象映射上时,自动展平将不会工作,这些对象映射定义在配置了subobjects: false的对象下:
-
enabled映射参数不能为false。 -
dynamic映射参数不能与父级的隐式或显式值相矛盾。例如,当映射的根目录中将dynamic设置为false时,设置dynamic为true的对象映射器不能被自动展平。 -
subobjects映射参数不能显式设置为true。
PUT my-index-000002
{
"mappings": {
"properties": {
"metrics": {
"subobjects": false,
"properties": {
"time": {
"type": "object",
"properties": {
"min": { "type": "long" },
"max": { "type": "long" }
}
}
}
}
}
}
}
GET my-index-000002/_mapping
term_vector
edit词向量包含关于由分析过程生成的术语的信息,包括:
- 术语列表。
- 每个术语的位置(或顺序)。
- 开始和结束字符偏移量,将术语映射到其在原始字符串中的起始位置。
- 有效载荷(如果可用)——与每个术语位置关联的用户定义的二进制数据。
这些词向量可以被存储,以便它们可以被检索用于特定的文档。
The term_vector 设置接受:
|
|
不存储术语向量。(默认) |
|
|
仅存储字段中的术语。 |
|
|
条款和职位被存储。 |
|
|
术语和字符偏移量被存储。 |
|
|
条款、位置和字符偏移量被存储。 |
|
|
条款、职位和有效载荷被存储。 |
|
|
术语、位置、偏移量和有效载荷被存储。 |
快速向量高亮器需要 with_positions_offsets。
术语向量API 可以检索存储的任何内容。
设置 with_positions_offsets 将会使字段的索引大小翻倍。
PUT my-index-000001
{
"mappings": {
"properties": {
"text": {
"type": "text",
"term_vector": "with_positions_offsets"
}
}
}
}
PUT my-index-000001/_doc/1
{
"text": "Quick brown fox"
}
GET my-index-000001/_search
{
"query": {
"match": {
"text": "brown fox"
}
},
"highlight": {
"fields": {
"text": {}
}
}
}