映射参数

edit

以下页面提供了对字段映射所使用的各种映射参数的详细解释:

以下映射参数适用于部分或所有字段数据类型:

分析器

edit

只有 text 字段支持 analyzer 映射参数。

参数 analyzer 指定了用于在索引或搜索 text 字段时进行 分析器文本分析

除非使用 search_analyzer 映射参数覆盖,否则此分析器将用于 索引和搜索分析。请参阅 指定分析器

我们建议在生产环境中使用之前测试分析器。请参阅 测试分析器

在现有字段上使用更新映射API时,analyzer设置不能被更新。

search_quote_analyzer

edit

The search_quote_analyzer 设置允许您为短语指定一个分析器,这在处理禁用短语查询的停用词时特别有用。

要禁用短语的字段停用词,需要使用三个分析器设置的字段:

  1. 用于索引所有术语(包括停用词)的analyzer设置
  2. 用于非短语查询的search_analyzer设置,将移除停用词
  3. 用于短语查询的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设置。

my_analyzer 分析器,用于标记所有术语,包括停用词

my_stop_analyzer 分析器,用于移除停用词

analyzer 设置指向 my_analyzer 分析器,该分析器将在索引时使用

search_analyzer 设置指向 my_stop_analyzer,并移除非短语查询的停用词

search_quote_analyzer 设置指向 my_analyzer 分析器,并确保停止词不会从短语查询中移除

由于查询被引号包围,因此被检测为短语查询,因此search_quote_analyzer生效,并确保停用词不会从查询中移除。my_analyzer分析器将返回以下标记 [the, quick, brown, fox],这将匹配其中一个文档。同时,术语查询将使用my_stop_analyzer分析器进行分析,该分析器将过滤掉停用词。因此,搜索The quick brown foxA quick brown fox都将返回两个文档,因为两个文档都包含以下标记 [quick, brown, fox]。如果没有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" 
}

字段 number_one 将包含整数 10

此文档将被拒绝,因为强制执行已禁用。

可以使用更新映射API更新现有字段上的coerce设置值。

索引级默认值

edit

可以在索引级别设置 index.mapping.coerce 设置,以全局禁用所有映射类型的强制转换:

PUT my-index-000001
{
  "settings": {
    "index.mapping.coerce": false
  },
  "mappings": {
    "properties": {
      "number_one": {
        "type": "integer",
        "coerce": true
      },
      "number_two": {
        "type": "integer"
      }
    }
  }
}

PUT my-index-000001/_doc/1
{ "number_one": "10" } 

PUT my-index-000001/_doc/2
{ "number_two": "10" } 

字段 number_one 覆盖了索引级别的设置以启用强制转换。

此文档将被拒绝,因为 number_two 字段继承了索引级别的强制设置。

copy_to

edit

参数 copy_to 允许你将多个字段的值复制到一个组字段中,然后可以将其作为一个单一字段进行查询。

如果你经常搜索多个字段,可以通过使用copy_to来减少搜索字段,从而提高搜索速度。请参阅尽量减少搜索字段

例如,可以将 first_namelast_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"
      }
    }
  }
}

first_namelast_name 字段的值复制到 full_name 字段中。

字段 first_namelast_name 仍然可以分别查询名字和姓氏,但字段 full_name 可以同时查询名字和姓氏。

一些重要点:

  • 复制的是字段,而不是术语(术语是分析过程的结果)。
  • 原始的_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与动态映射时,请考虑以下几点:

  • 如果目标字段在索引映射中不存在,通常的 动态映射行为适用。默认情况下,当 dynamic设置为true时,不存在的目标字段将动态添加到索引映射中。
  • 如果dynamic设置为false,目标字段将不会添加到索引映射中,并且值将不会被复制。
  • 如果dynamic设置为strict,复制到不存在的字段将导致错误。

    • 如果目标字段是嵌套的,那么copy_to字段必须指定嵌套字段的全路径。 省略全路径将导致strict_dynamic_mapping_exception。 使用"copy_to": ["parent_field.child_field"]来正确地定位一个嵌套字段。

      例如:

      PUT /test_index
      {
        "mappings": {
          "dynamic": "strict",
          "properties": {
            "description": {
              "properties": {
                "notes": {
                  "type": "text",
                  "copy_to": [ "description.notes_raw"], 
                  "analyzer": "standard",
                  "search_analyzer": "standard"
                },
                "notes_raw": {
                  "type": "keyword"
                }
              }
            }
          }
        }
      }

字段 notes 被复制到字段 notes_raw。仅针对 notes_raw 而不是 description.notes_raw 会导致 strict_dynamic_mapping_exception

在这个例子中,notes_raw 没有在映射的根目录下定义,而是在 description 字段下。 如果没有完全限定的路径,Elasticsearch 会将 copy_to 目标解释为根级别的字段,而不是 description 下的嵌套字段。

doc_values

edit

大多数字段默认是索引的,这使得它们可以被搜索。倒排索引允许查询在唯一的排序术语列表中查找搜索术语,并立即访问包含该术语的文档列表。

排序、聚合和在脚本中访问字段值需要不同的数据访问模式。我们需要能够查找文档并找到其在某个字段中的术语,而不是查找术语并找到文档。

Doc values 是在文档索引时构建的磁盘数据结构,使得这种数据访问模式成为可能。它们存储与 _source 相同的值,但以面向列的方式存储,这种方式对于排序和聚合更加高效。Doc values 几乎支持所有字段类型,但 值得注意的是,textannotated_text 字段除外

仅文档值字段

edit

数字类型, 日期类型, 布尔类型, IP类型, 地理点类型关键词类型 也可以在它们未被索引但仅启用了文档值时进行查询。 在文档值上的查询性能比在索引结构上慢得多,但对于那些仅偶尔查询且查询性能不那么重要的字段来说,它在磁盘使用和查询性能之间提供了一个有趣的权衡。这使得仅文档值字段非常适合那些不期望通常用于过滤的字段,例如指标数据上的仪表或计数器。

仅文档值字段可以按如下方式配置:

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "status_code": { 
        "type":  "long"
      },
      "session_id": { 
        "type":  "long",
        "index": false
      }
    }
  }
}

The status_code 字段是一个常规的长整型字段。

字段 session_idindex 已禁用,因此它是一个仅文档值的长字段,因为默认情况下启用了文档值。

禁用文档值

edit

所有支持文档值的字段默认情况下都启用了它们。如果您确定不需要对某个字段进行排序或聚合,或者从脚本中访问该字段的值,您可以禁用文档值以节省磁盘空间:

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "status_code": { 
        "type":       "keyword"
      },
      "session_id": { 
        "type":       "keyword",
        "doc_values": false
      }
    }
  }
}

字段 status_code 默认启用了 doc_values

The session_iddoc_values 被禁用,但仍然可以查询。

您不能为wildcard字段禁用doc值。

dynamic

edit

当你索引一个包含新字段的文档时,Elasticsearch 动态地添加该字段到文档或文档内的嵌套对象中。以下文档添加了字符串字段 username,对象字段 name,以及在 name 对象下的两个字符串字段:

PUT my-index-000001/_doc/1
{
  "username": "johnsmith",
  "name": { 
    "first": "John",
    "last": "Smith"
  }
}

GET my-index-000001/_mapping 

参考name对象下的字段为name.firstname.last

检查映射以查看更改。

以下文档添加了两个字符串字段:emailname.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 对象启用了动态映射,因此您可以向这个内部对象添加字段。

PUT my-index-000001
{
  "mappings": {
    "dynamic": false, 
    "properties": {
      "user": { 
        "properties": {
          "name": {
            "type": "text"
          },
          "social_networks": {
            "dynamic": true, 
            "properties": {}
          }
        }
      }
    }
  }
}

在类型级别禁用动态映射。

The user 对象继承了类型级别的设置。

为此内部对象启用动态映射。

用于动态的参数

edit

参数 dynamic 控制是否动态添加新字段,并接受以下参数:

新字段被添加到映射中(默认)。

运行时

新字段作为 运行时字段 添加到映射中。 这些字段未被索引,并且在查询时从 _source 加载。

新字段将被忽略。这些字段将不会被索引或搜索,但仍会出现在返回的命中结果的 _source 字段中。这些字段不会被添加到映射中,并且新字段必须显式添加。

严格

如果检测到新字段,则会抛出异常并且文档被拒绝。新字段必须显式添加到映射中。

达到字段限制时的行为

edit

dynamic 设置为 trueruntime 只会添加动态字段,直到达到 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 创建了一个称为全局序号的统一映射。全局序号映射建立在段序号之上,通过维护一个从全局序号到每个段本地序号的映射来工作。

如果搜索包含以下任何组件,则使用全局序号:

  • keywordipflattened字段进行某些桶聚合。这包括如上所述的terms聚合,以及compositediversified_samplersignificant_terms
  • 对需要启用fielddatatext字段进行桶聚合。
  • 对来自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

通常,全局序数在加载时间和内存使用方面不会带来很大的开销。然而,在具有大分片的索引上,或者如果字段包含大量唯一项值,加载全局序数可能会很昂贵。因为全局序数为分片上的所有段提供了一个统一的映射,所以当一个新的段变得可见时,它们也需要完全重建。

在某些情况下,可以完全避免全局序数加载:

  • termssamplersignificant_terms 聚合支持一个参数 execution_hint 用于控制如何收集桶。它默认设置为 global_ordinals, 但可以设置为 map 以直接使用术语值。
  • 如果一个分片已经被 强制合并 到一个单一 段,那么它的段序数已经是分片的 全局 序数。在这种情况下,Elasticsearch 不需要构建全局序数映射, 使用全局序数不会产生额外的开销。请注意,出于性能原因,您应该仅对不再写入的索引进行强制合并。

启用

edit

Elasticsearch 会尝试索引你提供的所有字段,但有时你只想存储字段而不对其进行索引。例如,想象一下你正在使用 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"
}

字段 session_data 已禁用。

任何任意数据都可以传递到 session_data 字段,因为它将被完全忽略。

The session_data 也会忽略不是 JSON 对象的值。

整个映射也可以被禁用,在这种情况下,文档存储在_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 完全跳过解析字段内容,因此可以将非对象数据添加到已禁用的字段中:

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "session_data": {
        "type": "object",
        "enabled": false
      }
    }
  }
}

PUT my-index-000001/_doc/session_1
{
  "session_data": "foo bar" 
}

文档添加成功,尽管 session_data 包含非对象数据。

格式

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定义的周年,但使用YWw字段说明符的自定义格式化程序使用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_VALUELong.MAX_VALUE 的限制。
epoch_second
一个用于自纪元以来的秒数的格式化器。请注意,这个时间戳受到Java Long.MIN_VALUELong. MAX_VALUE 除以1000(每秒的毫秒数)的限制。
date_optional_time or strict_date_optional_time

一个通用的ISO日期时间解析器,其中日期必须至少包含年份,时间(由T分隔)是可选的。 示例:yyyy-MM-dd'T'HH:mm:ss.SSSZyyyy-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.SSSSSSZyyyy-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_date or strict_basic_week_date
一个完整的日期基本格式化器,格式为四位数的周年份、两位数的周数和一位数的星期几:xxxx'W'wwe
basic_week_date_time or strict_basic_week_date_time
一个基本的格式化器,结合了基本的周年度日期和时间,由T分隔:xxxx'W'wwe'T'HHmmss.SSSZ
basic_week_date_time_no_millis or strict_basic_week_date_time_no_millis
一个基本的格式化器,结合了基本的周年度日期和时间,不带毫秒,由T分隔:xxxx'W'wwe'T'HHmmssZ
date or strict_date
一个用于显示完整日期的格式化器,格式为四位数的年份、两位数的月份和两位数的日期:yyyy-MM-dd
date_hour or strict_date_hour
一个结合了完整日期和两位数小时的格式化器: yyyy-MM-dd'T'HH
date_hour_minute or strict_date_hour_minute
一个结合了完整日期、两位数的小时和两位数的分钟的格式化器:yyyy-MM-dd'T'HH:mm
date_hour_minute_second or strict_date_hour_minute_second
一个结合了完整日期、两位数的小时、两位数的分钟和两位数的秒的格式化器:yyyy-MM-dd'T'HH:mm:ss
date_hour_minute_second_fraction or strict_date_hour_minute_second_fraction
一个格式化器,结合了完整的日期、两位数的小时、两位数的分钟、两位数的秒和三位数的秒的小数部分:yyyy-MM-dd'T'HH:mm:ss.SSS
date_hour_minute_second_millis or strict_date_hour_minute_second_millis
一个格式化器,结合了完整日期、两位数的小时、两位数的分钟、两位数的秒和三位数的秒的小数部分:yyyy-MM-dd'T'HH:mm:ss.SSS
date_time or strict_date_time
一个结合了完整日期和时间的格式化器,由T分隔: yyyy-MM-dd'T'HH:mm:ss.SSSZ
date_time_no_millis or strict_date_time_no_millis
一个结合了不带毫秒的完整日期和时间的格式化器,由T分隔:yyyy-MM-dd'T'HH:mm:ssZ
hour or strict_hour
一天中的两位数小时格式化器:HH
hour_minute or strict_hour_minute
一天中的两位数小时和小时的两位数分钟的格式化器: HH:mm
hour_minute_second or strict_hour_minute_second
一天中的两位数小时,一小时的两位数分钟,以及一分钟中的两位数秒的格式化器:HH:mm:ss
hour_minute_second_fraction or strict_hour_minute_second_fraction
一天中的两位数小时,小时的两位数分钟,分钟的两位数秒,以及秒的三位数分数的格式化器:HH:mm:ss.SSS
hour_minute_second_millis or strict_hour_minute_second_millis
一天中的两位数小时,小时的两位数分钟,分钟的两位数秒,以及秒的三位数分数的格式化器:HH:mm:ss.SSS
ordinal_date or strict_ordinal_date
一个用于完整序数日期的格式化器,使用四位数的年份和三位数的dayOfYear:yyyy-DDD
ordinal_date_time or strict_ordinal_date_time
一个用于完整序数日期和时间的格式化器,使用四位数的年和三位数的dayOfYear:yyyy-DDD'T'HH:mm:ss.SSSZ
ordinal_date_time_no_millis or strict_ordinal_date_time_no_millis
一个用于完整序数日期和时间的格式化器,不包括毫秒,使用四位数年份和三位数的天数:yyyy-DDD'T'HH:mm:ssZ
time or strict_time
一个用于表示两位数的小时、两位数的分钟、两位数的秒、三位数的秒的小数部分以及时区偏移的格式化器:HH:mm:ss.SSSZ
time_no_millis or strict_time_no_millis
一天中的两位数小时,小时的两位数分钟,分钟的两位数秒,以及时区偏移的格式化器:HH:mm:ssZ
t_time or strict_t_time
一个用于表示两位数的小时、两位数的分钟、两位数的秒、三位数的秒的小数部分以及以T为前缀的时区偏移的格式化器:'T'HH:mm:ss.SSSZ
t_time_no_millis or strict_t_time_no_millis
一个用于表示两位数的小时、两位数的分钟、两位数的秒以及以T为前缀的时区偏移的格式化器:'T'HH:mm:ssZ
week_date or strict_week_date
一个用于完整日期的格式化器,格式为四位数的周年份、两位数的周数和一位数的星期几:YYYY-'W'ww-e。 这使用了ISO周日期定义。
week_date_time or strict_week_date_time
一个结合了完整周年和时间的格式化器,由T分隔:YYYY-'W'ww-e'T'HH:mm:ss.SSSZ。 这使用了ISO周日期定义。
week_date_time_no_millis or strict_week_date_time_no_millis
一个结合了完整周年和时间(不含毫秒)的格式化器,由T分隔:YYYY-'W'ww-e'T'HH:mm:ssZ。 这使用了ISO周日期定义。
weekyear or strict_weekyear
一个用于四位数周年的格式化器:YYYY。 这使用了ISO周日期定义。
weekyear_week or strict_weekyear_week
一个用于四位数年份和两位数周数的格式化器: YYYY-'W'ww。 这使用了ISO周日期定义。
weekyear_week_day or strict_weekyear_week_day
一个用于四位数年份、两位数周数和一位数星期几的格式化器:YYYY-'W'ww-e。 这使用了ISO周日期定义。
year or strict_year
四位数年份的格式化器:yyyy
year_month or strict_year_month
一个用于四位数年份和两位数月份的年份格式化器:yyyy-MM
year_month_day or strict_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"
      }
    }
  }
}

此字段将忽略任何超过20个字符的字符串。

此文档已成功索引。

本文档将被索引,但不包括索引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 在索引级别应用。此设置允许您为索引中的所有适用字段定义最大字符串长度,包括 keywordwildcard 以及 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" 
}

本文档将对text字段进行索引,但不包括number_one字段。

此文档将被拒绝,因为 number_two 不允许格式错误的数据。

目前,ignore_malformed 设置由以下 映射类型 支持:

Numeric
long, integer, short, byte, double, float, half_float, scaled_float
Boolean
布尔值
Date
日期
Date nanoseconds
date_nanos
Geopoint
geo_point 用于纬度/经度点
Geoshape
geo_shape 用于复杂形状,如多边形
IP
ip 用于IPv4和IPv6地址

可以使用更新映射API更新现有字段上的ignore_malformed设置值。

索引级别默认值

edit

可以在索引级别设置 index.mapping.ignore_malformed 设置,以全局忽略所有允许的映射类型中的格式错误内容。 不支持该设置的映射类型如果在索引级别设置,将会忽略它。

PUT my-index-000001
{
  "settings": {
    "index.mapping.ignore_malformed": true 
  },
  "mappings": {
    "properties": {
      "number_one": { 
        "type": "byte"
      },
      "number_two": {
        "type": "integer",
        "ignore_malformed": false 
      }
    }
  }
}

字段 number_one 继承了索引级别的设置。

字段 number_two 覆盖了索引级别的设置,以关闭 ignore_malformed

处理格式错误字段

edit

ignore_malformed开启时,格式错误的字段在索引时会被静默忽略。建议尽可能减少包含格式错误字段的文档数量,否则对该字段的查询将变得无意义。Elasticsearch 通过在特殊字段_ignored上使用existstermterms查询,可以轻松检查有多少文档包含格式错误的字段。

JSON对象的限制

edit

您不能将 ignore_malformed 与以下数据类型一起使用:

您也不能使用 ignore_malformed 来忽略提交给错误数据类型字段的 JSON 对象。JSON 对象是任何被大括号 "{}" 包围的数据,并包括映射到嵌套、对象和范围数据类型的数据。

如果您将JSON对象提交到不支持的字段,Elasticsearch将返回错误并拒绝整个文档,无论ignore_malformed设置如何。

索引

edit

选项index控制字段值是否被索引。它接受truefalse,默认为true

为字段建立索引会创建数据结构,使得该字段能够被高效查询。数字类型日期类型布尔类型IP类型地理点类型以及 关键字类型在未索引但启用了文档值时也可以查询。 但这些字段的查询速度较慢,因为需要进行全索引扫描。所有其他字段均不可查询。

索引选项

edit

参数 index_options 控制了为了搜索和突出显示目的而添加到倒排索引中的信息。只有基于词项的字段类型,如 textkeyword,支持此配置。

该参数接受以下值之一。每个值从前面的值中检索信息。例如,freqs 包含 docspositions 包含 freqsdocs

docs
仅索引文档编号。可以回答问题 这个术语是否存在于这个字段中?
freqs
文档编号和词频被索引。词频用于将重复的词的得分高于单个词。
positions (default)
文档编号、词频和词位置(或顺序)被索引。 位置可用于邻近或短语查询
offsets
文档编号、词频、位置以及起始和结束字符偏移量(用于将术语映射回原始字符串)都会被索引。偏移量由统一高亮器用于加速高亮显示。
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "text": {
        "type": "text",
        "index_options": "offsets"
      }
    }
  }
}

PUT my-index-000001/_doc/1
{
  "text": "Quick brown fox"
}

GET my-index-000001/_search
{
  "query": {
    "match": {
      "text": "brown fox"
    }
  },
  "highlight": {
    "fields": {
      "text": {} 
    }
  }
}

默认情况下,text 字段将使用 postings 进行高亮显示,因为 offsets 已索引。

index_phrases

edit

如果启用,双词组合(shingles)将被索引到一个单独的字段中。这使得精确短语查询(无偏差)能够更高效地运行,但代价是索引更大。请注意,当停用词未被移除时,此功能效果最佳,因为包含停用词的短语将不会使用辅助字段,而是回退到标准短语查询。接受 truefalse(默认)。

index_prefixes

edit

参数 index_prefixes 启用了术语前缀的索引,以加快前缀搜索的速度。它接受以下可选设置:

min_chars

要索引的最小前缀长度。必须大于 0,默认值为 2。该值包含在内。

max_chars

要索引的最大前缀长度。必须小于20,默认值为5。 该值是包含的。

此示例使用默认的前缀长度设置创建一个文本字段:

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "body_text": {
        "type": "text",
        "index_prefixes": { }    
      }
    }
  }
}

一个空的设置对象将使用默认的 min_charsmax_chars 设置

此示例使用自定义前缀长度设置:

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" 
      }
    }
  }
}

The city.raw 字段是 city 字段的 keyword 版本。

字段 city 可以用于全文搜索。

字段 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 text field uses the standard analyzer.

The text.english 字段使用 english 分析器。

索引两个文档,一个包含fox,另一个包含foxes

查询 texttext.english 字段并合并分数。

字段 text 在第一个文档中包含术语 fox,在第二个文档中包含 foxes。字段 text.english 在两个文档中都包含 fox,因为 foxes 被词干化为 fox

查询字符串也会被standard分析器分析用于text字段,并且被english分析器分析用于text.english字段。词干化字段允许查询foxes也能匹配包含fox的文档。这使得我们能够匹配尽可能多的文档。通过同时查询未词干化的text字段,我们提高了精确匹配foxes的文档的相关性评分。

normalizer

edit

字段 keywordnormalizer 属性类似于 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

edit

Norms 存储各种归一化因子,这些因子在查询时用于计算文档相对于查询的得分。

尽管对于评分很有用,但规范也需要相当多的磁盘空间(通常在你的索引中,每个字段每个文档大约需要一个字节,即使文档没有这个特定字段)。因此,如果你不需要对特定字段进行评分,你应该禁用该字段的规范。特别是,这对于仅用于过滤或聚合的字段来说,是这种情况。

可以使用更新映射 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" 
    }
  }
}

将显式的 null 值替换为术语 NULL

一个空数组不包含显式的 null,因此不会被替换为 null_value

查询 NULL 返回文档1,但不返回文档2。

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 
      }
    }
  }
}

这个短语查询没有匹配到我们的文档,这是完全预期的。

即使 AbrahamLincoln 位于不同的字符串中,这个短语查询仍然匹配我们的文档,因为 slop > position_increment_gap

可以在映射中指定position_increment_gap。例如:

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "names": {
        "type": "text",
        "position_increment_gap": 0 
      }
    }
  }
}

PUT my-index-000001/_doc/1
{
  "names": [ "John Abraham", "Lincoln Smith"]
}

GET my-index-000001/_search
{
  "query": {
    "match_phrase": {
      "names": "Abraham Lincoln" 
    }
  }
}

下一个数组元素中的第一个项将与前一个数组元素中的最后一个项相隔0项。

短语查询匹配了我们的文档,这很奇怪,但这正是我们在映射中所要求的。

属性

edit

类型映射、对象字段嵌套字段 包含子字段,称为属性。这些属性可以是任何 数据类型,包括对象嵌套。可以添加属性:

  • 通过在创建索引时明确定义它们。
  • 通过在使用更新映射 API 添加或更新映射类型时明确定义它们。
  • 通过动态索引包含新字段的文档。

下面是一个向映射类型、对象字段和嵌套字段添加属性的示例:

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
    }
  ]
}

顶级映射定义中的属性。

manager 对象字段下的属性。

employees 嵌套字段下的属性。

一个与上述映射相对应的示例文档。

允许为同一索引中同名字段设置不同的 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"
      }
    }
  }
}

分析设置以定义自定义的 autocomplete 分析器。

在索引时,text 字段使用 autocomplete 分析器,但在搜索时使用 standard 分析器。

此字段被索引为以下词项:[ q, qu, qui, quic, quick, b, br, bro, brow, brown, f, fo, fox ]

查询搜索这两个词:[ quick, br ]

请参阅索引时即搜即得以获取此示例的完整解释。

可以使用更新映射API更新现有字段上的search_analyzer设置。请注意,为此,需要在更新的字段定义中重复任何现有的“analyzer”设置和“type”。

相似性

edit

Elasticsearch 允许您为每个字段配置一个文本评分算法或 相似性similarity 设置提供了一种简单的方法来选择除默认 BM25 之外的文本相似性算法,例如 boolean

仅支持基于文本的字段类型,如 textkeyword 支持此配置。

可以通过调整内置相似度的参数来配置自定义相似度。有关此专家选项的更多详细信息,请参阅相似度模块

无需任何进一步配置即可直接使用的唯一相似性是:

BM25
Okapi BM25算法。Elasticsearch和Lucene中默认使用的算法。
boolean
一个简单的布尔相似度,用于不需要全文排序且分数仅基于查询词是否匹配的情况。布尔相似度为词项赋予的分数等于它们的查询提升值。

可以在首次创建字段时在字段级别设置相似度,如下所示:

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "default_field": { 
        "type": "text"
      },
      "boolean_sim_field": {
        "type": "text",
        "similarity": "boolean" 
      }
    }
  }
}

The default_field 使用 BM25 相似度。

The boolean_sim_field 使用 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" ] 
}

存储了titledate字段。

此请求将检索titledate字段的值。

存储字段返回为数组

为了保持一致性,存储的字段总是以数组的形式返回,因为无法知道原始字段值是单个值、多个值还是空数组。

如果你需要原始值,你应该从_source字段中获取它。

子对象

edit

在索引文档或更新映射时,Elasticsearch 接受包含点号的字段名称,这些名称会被扩展为其对应的对象结构。例如,字段 metrics.time.max 被映射为一个 max 叶子字段,其父对象为 time,而 time 又属于其父对象 metrics

所述的默认行为在大多数场景下是合理的,但在某些情况下会导致问题,例如当字段 metrics.time 也包含一个值时,这在索引度量数据时很常见。如果一个文档同时包含 metrics.time.maxmetrics.time 的值,则该文档会被拒绝,因为 time 需要同时作为叶子字段来保存值,并且作为对象来保存 max 子字段。

设置subobjects,该设置仅适用于顶级映射定义和object字段,禁用了对象持有进一步子对象的能力,并使得存储字段名称包含点和共享公共前缀的文档成为可能。从上面的例子来看,如果对象容器metricssubobjects设置为false,它可以直接保存timetime.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"
            }
          }
        }
      }
    }
  }
}

The metrics 字段不能包含其他对象。

示例文档,包含平面路径

示例文档,包含一个对象(配置为不包含子对象)及其叶子子字段

生成的映射,其中字段名称中的点被保留

整个映射可能被配置为不支持子对象,在这种情况下,文档只能包含叶子子字段:

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 时,设置 dynamictrue 的对象映射器不能被自动展平。
  • 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
{
  "my-index-000002" : {
    "mappings" : {
      "properties" : {
        "metrics" : {
          "subobjects" : false,
          "properties" : {
            "time.min" : { 
              "type" : "long"
            },
            "time.max" : {
              "type" : "long"
            }
          }
        }
      }
    }
  }
}

metrics 对象可以包含进一步的对象映射,这些映射将被自动展平。 在此级别的对象映射不得设置某些映射参数,如上所述。

此字段将在映射存储之前自动展平为"time.min"

可以通过查看索引映射来检查自动展平的"time.min"字段。

term_vector

edit

词向量包含关于由分析过程生成的术语的信息,包括:

  • 术语列表。
  • 每个术语的位置(或顺序)。
  • 开始和结束字符偏移量,将术语映射到其在原始字符串中的起始位置。
  • 有效载荷(如果可用)——与每个术语位置关联的用户定义的二进制数据。

这些词向量可以被存储,以便它们可以被检索用于特定的文档。

The term_vector 设置接受:

不存储术语向量。(默认)

仅存储字段中的术语。

with_positions

条款和职位被存储。

with_offsets

术语和字符偏移量被存储。

with_positions_offsets

条款、位置和字符偏移量被存储。

with_positions_payloads

条款、职位和有效载荷被存储。

with_positions_offsets_payloads

术语、位置、偏移量和有效载荷被存储。

快速向量高亮器需要 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": {} 
    }
  }
}

默认情况下,将使用快速向量高亮器来处理text字段,因为启用了词向量。