58同城烟台网站建设怎么下载文件
web/
2025/10/2 1:02:10/
文章来源:
58同城烟台网站建设,怎么下载文件,营销型网站方案,关键词seo是什么es创建映射和设置 一、什么是 Elasticsearch 映射#xff1f;二、映射中的字段类型常见字段类型 #xff08;Common data types#xff09;对象和关联类型#xff08;Objects and relational types#xff09;结构化数据类型#xff08;Structured data types#xff09… es创建映射和设置 一、什么是 Elasticsearch 映射二、映射中的字段类型常见字段类型 Common data types对象和关联类型Objects and relational types结构化数据类型Structured data types聚合数据类型Aggregate data types文本搜索类型Text search types文档排名类型Document ranking types空间数据类型Spatial data types其他类型other types数组Arrays多字段multi-fields 三、映射限制 Mapping limit settings四、创建映射使用 REST API 创建映射常用映射示例和说明文本字段映射关键字字段映射日期字段映射数值字段映射地理位置字段映射 特殊映射嵌套字段多字段支持自定义分析器 五、官方文档翻译可做显式映射 Explicit mapping聚合度量字段类型 Aggregate metric field type别名字段类型 Alias数组 Arrays布尔字段类型 Boolean field type日期字段类型 Date日期纳秒字段类型 Date nanoseconds field type密集向量字段类型 Dense vector field type展平字段类型 Flattened field type地理点字段类型 Geopoint field type地理形状字段类型 Geo Shape Field Type直方图字段类型 Histogramip字段类型 IP父子关系字段类型 join关键字类型 Keyword type family嵌套字段类型 Nested field type数值字段类型 Numeric对象字段类型 objecdtPercolator字段类型point数据类型范围字段类型 range特征排名字段类型 rank_feature排名特征字段类型 rank_features形状 shape文本 TextToken count字段类型无符号长整数 Unsigned long版本字段类型 Version元数据字段 Metadata fields 元数据字段 Metadata fields映射参数 Mapping parameters映射限制删除映射类型 官方地址Mapping
一、什么是 Elasticsearch 映射
在 Elasticsearch 中映射是索引的关键组成部分它定义了文档的结构和字段。每个文档都包含一个或多个字段而映射定义了这些字段的数据类型、如何分析文本、字段是否可搜索等信息。
映射的主要作用包括 定义字段类型你可以指定字段是文本、数字、日期、地理位置等数据类型。 文本分析决定如何对文本字段进行分析例如拆分为单词、去除停用词、转换大小写等。 字段是否存储你可以设置字段是否需要存储原始值以便在检索时使用。 索引选项控制字段是否被索引以及如何索引。 多字段支持Elasticsearch 允许你创建多个字段别名以便更好地支持不同类型的查询。 复杂数据类型Elasticsearch 支持复杂数据类型如对象、数组和嵌套字段。
二、映射中的字段类型
来自官方翻译
常见字段类型 Common data types
二进制binary以Base64字符串编码的二进制值。布尔值booleantrue 和 false 值。关键字Keywords包括关键字keyword、常量关键字constant_keyword和通配符wildcard。数值Numbers数值类型如长整型long和双精度浮点型double用于表示数量。日期Dates日期类型包括日期date和日期纳秒精度date_nanos。别名alias定义现有字段的别名。
对象和关联类型Objects and relational types
objectJSON对象。flattened将整个JSON对象作为单个字段值。nested保留JSON对象子字段之间的关系。join定义同一索引中文档之间的父子关系。
结构化数据类型Structured data types
Range范围类型如 long_range、double_range、date_range 和 ip_range。ipIPv4 和 IPv6 地址。version软件版本。支持语义化版本优先规则。murmur3计算并存储值的哈希。
聚合数据类型Aggregate data types
aggregate_metric_double预聚合的度量值。histogram以直方图形式预聚合的数值。
文本搜索类型Text search types
text fields文本字段包括text和match_only_text。经过分析的、非结构化的文本。annotated-text包含特殊标记的文本用于识别命名实体。completion用于自动完成建议。search_as_you_type类似文本的类型用于按输入实时完成建议。token_count文本中标记的计数。
文档排名类型Document ranking types
dense_vector记录浮点值的密集向量。sparse_vector记录浮点值的稀疏向量。rank_feature记录一个数值特征以在查询时提高命中。rank_features记录数值特征以在查询时提高命中。
空间数据类型Spatial data types
geo_point纬度和经度点。geo_shape复杂的形状例如多边形。point任意笛卡尔坐标点。shape任意笛卡尔几何图形。
其他类型other types
percolator索引使用 Query DSL 编写的查询。
数组Arrays
Elasticsearch 中数组不需要专门的字段数据类型。默认情况下任何字段可以包含零个或多个值但数组中的所有值必须属于相同的字段类型。有关更多信息请参阅数组。
多字段multi-fields
通常对于不同目的将同一字段以不同方式进行索引很有用。例如将字符串字段映射为文本字段以进行全文搜索将其映射为关键字字段以进行排序或聚合。或者可以使用标准分析器、英语分析器和法语分析器对文本字段进行索引。
这就是多字段的目的。大多数字段类型支持多字段通过 fields 参数实现。
三、映射限制 Mapping limit settings
以下是用于限制字段映射数量以防止映射爆炸的设置 index.mapping.total_fields.limit这是索引中字段的最大数量。字段和对象映射以及字段别名都计入这一限制。默认值为1000。此限制旨在防止映射和搜索变得过大。较高的值可能导致性能下降和内存问题尤其是在负载较高或资源较少的集群中。如果您增加此设置建议同时增加indices.query.bool.max_clause_count设置该设置限制了查询中的布尔子句的最大数量。 index.mapping.depth.limit这是字段的最大深度以内部对象数量来衡量。例如如果所有字段都在根对象级别定义那么深度为1。如果存在一个对象映射则深度为2依此类推。默认值为20。 index.mapping.nested_fields.limit这是索引中不同嵌套映射的最大数量。嵌套类型应仅在特殊情况下使用当需要独立查询对象数组时。为防止不良设计的映射此设置限制了每个索引中唯一嵌套类型的数量。默认值为50。 index.mapping.nested_objects.limit这是单个文档中包含的所有嵌套 JSON 对象的最大数量跨所有嵌套类型。此限制有助于防止文档包含过多嵌套对象时发生内存不足错误。默认值为10000。 index.mapping.field_name_length.limit此设置用于限制字段名称的最大长度。通常情况下不需要设置此设置因为默认设置是足够的除非用户开始添加具有非常长名称的大量字段。默认值是Long.MAX_VALUE没有限制。 index.mapping.dimension_fields.limit技术预览此功能处于技术预览阶段可能在将来的版本中更改或删除。它是 Elastic 内部使用的设置。
四、创建映射
创建映射是在 Elasticsearch 中定义索引结构的过程你可以使用 REST API 或 Elasticsearch客户端库执行此操作。
使用 REST API 创建映射
使用 PUT 请求指定映射配置创建了一个名为 my_index 的索引并定义了一些字段映射
PUT /my_index
{mappings: {properties: {title: {type: text,analyzer: standard},description: {type: text,analyzer: english},timestamp: {type: date}}}
}在这个示例中我们创建了一个索引 my_index 并定义了三个字段title、description 和 timestamp。下面是一些字段映射的常见示例和说明
常用映射示例和说明
文本字段映射
文本字段用于存储文本数据例如文章内容、产品描述等。以下是一个文本字段映射的示例
title: {type: text,analyzer: standard
}type 设置为 text 表示这是一个文本字段。analyzer 指定了用于分析文本的分析器。在这个示例中我们使用标准分析器它将文本拆分成单词并转换为小写。
关键字字段映射
关键字字段通常用于存储不分析的原始文本例如标签、类别等。以下是一个关键字字段映射的示例
tags: {type: keyword
}type 设置为 keyword 表示这是一个关键字字段。关键字字段不会被分析文本将以原样存储。
日期字段映射
日期字段用于存储日期和时间信息。以下是一个日期字段映射的示例
timestamp: {type: date
}type 设置为 date 表示这是一个日期字段。Elasticsearch 会自动解析日期格式。
数值字段映射
数值字段可用于存储数字数据如价格、评分等。以下是一个数值字段映射的示例
price: {type: float
}type 设置为 float 表示这是一个浮点数字段。
地理位置字段映射
地理位置字段用于存储地理坐标信息如经度和纬度。以下是一个地理位置字段映射的示例
location: {type: geo_point
}type 设置为 geo_point 表示这是一个地理位置字段。你可以用经度和纬度表示地理坐标。
特殊映射
当需要更复杂的数据结构和搜索需求时可以使用嵌套字段、多字段支持和自定义分析器等来扩展 Elasticsearch 映射。以下是这些示例
嵌套字段
嵌套字段允许你在文档中创建嵌套的 JSON 结构以表示复杂的关系。例如如果你想建立一个博客文章的索引每篇文章可以包含多个评论每个评论又可以包含作者信息和评论文本。以下是一个嵌套字段映射的示例
comments: {type: nested,properties: {author: {type: text},comment_text: {type: text}}
}在这个示例中创建了一个类型为 nested的 comments 字段并定义了 author 和 comment_text 作为嵌套字段。这能够在每篇文章中存储多个评论每个评论都有自己的作者和评论文本。
多字段支持
多字段支持允许为同一字段创建多个不同的表示以满足不同的查询需求。例如你可以为一个字段同时创建一个全文搜索版本和一个精确匹配版本。以下是一个多字段支持的示例
product_name: {type: text,fields: {standard: {type: text,analyzer: standard},keyword: {type: keyword}}
}在这个示例中创建了一个 product_name 字段其类型为 text然后定义了两个多字段standard 和 keyword。standard 多字段使用标准分析器用于全文搜索而 keyword 多字段使用 keyword 类型用于精确匹配。这同样配置可以同时执行全文搜索和精确匹配查询。
自定义分析器
自定义分析器允许你定义如何处理文本字段的文本分析。例如你可以创建一个自定义分析器来处理特定语言的文本去除停用词或执行其他自定义文本处理。以下是一个自定义分析器的示例
{settings: {analysis: {analyzer: {custom_analyzer: {type: custom,tokenizer: standard,filter: [lowercase, custom_filter]}},filter: {custom_filter: {type: stop,stopwords: [the, is, in, on, and]}}}},mappings: {properties: {content: {type: text,analyzer: custom_analyzer}}}
}在上述索引设置中我们配置了一个名为 “custom_analyzer” 的自定义分析器包括以下部分 tokenizer: standard使用标准分析器作为分词器。这将文本拆分为单词。 filter: [lowercase, custom_filter]使用过滤器链首先将文本转换为小写“lowercase” 过滤器然后应用自定义过滤器 “custom_filter”。 filter: custom_filter 中的 “stop” 过滤器定义了一组停用词“stopwords”。这些停用词将在文本分析过程中被过滤掉以提高搜索质量。
然后在索引映射中我们将 “content” 字段的分析器指定为 “custom_analyzer”这表示在索引和搜索 “content” 字段的文本时将使用自定义分析器进行处理。
五、官方文档翻译可做
显式映射 Explicit mapping
您对数据的了解比 Elasticsearch 所能猜测的还要多因此虽然动态映射对于入门很有用但在某些时候您会想要指定自己的显式映射。 您可以在创建索引并将字段添加到现有索引时创建字段映射。 创建具有显式映射的索引 您可以使用create index API来创建一个新的索引并定义其映射。
PUT /my-index-000001
{mappings: {properties: {age: { type: integer }, email: { type: keyword }, name: { type: text } }}
}这将创建以下字段
创建一个名为age的整数字段。创建一个名为email的关键字字段。创建一个名为name的文本字段。
向现有映射添加字段 您可以使用update mapping API向现有索引添加一个或多个新字段。以下示例向现有索引添加一个名为employee-id的关键字字段同时将该字段的index参数值设置为false表示employee-id字段的值将被存储但不会被索引或用于搜索。
PUT /my-index-000001/_mapping
{properties: {employee-id: {type: keyword,index: false}}
}更新字段的映射 除了受支持的映射参数外您无法更改现有字段的映射或字段类型。更改现有字段可能会使已经索引的数据无效。如果需要更改数据流支持的索引的字段映射请参阅更改数据流的映射和设置。如果需要更改其他索引中的字段映射请创建一个具有正确映射的新索引并将数据重新索引到该索引中。重命名字段将使已经使用旧字段名称索引的数据无效。相反可以添加一个别名字段来创建一个替代字段名称。
要查看索引的映射您可以使用get mapping API。
GET /my-index-000001/_mapping此API将返回如下响应
{my-index-000001 : {mappings : {properties : {age : {type : integer},email : {type : keyword},employee-id : {type : keyword,index : false},name : {type : text}}}}
}如果只想查看一个或多个特定字段的映射您可以使用get field mapping API。这在您不需要完整的索引映射或索引包含大量字段时非常有用。
以下请求检索employee-id字段的映射。
GET /my-index-000001/_mapping/field/employee-id此API将返回如下响应
{my-index-000001 : {mappings : {employee-id : {full_name : employee-id,mapping : {employee-id : {type : keyword,index : false}}}}}
}聚合度量字段类型 Aggregate metric field type
聚合度量字段类型用于存储预先聚合的数值数据以供度量聚合使用。aggregate_metric_double字段是一个包含以下度量子字段之一的对象min、max、sum和value_count。
当您对aggregate_metric_double字段运行特定的度量聚合时聚合会使用相关的子字段值。例如在aggregate_metric_double字段上运行min聚合将返回所有min子字段的最小值。
aggregate_metric_double字段为每个度量子字段存储单个数值文档值。不支持数组值。min、max和sum的值是双精度浮点数value_count是正整数。
以下是一个示例请求演示如何在索引中创建aggregate_metric_double字段
PUT my-index
{mappings: {properties: {my-agg-metric-field: {type: aggregate_metric_double,metrics: [ min, max, sum, value_count ],default_metric: max}}}
}aggregate_metric_double字段的参数包括
metrics必需度量子字段的字符串数组每个值对应一个度量聚合。有效值包括min、max、sum和value_count必须至少指定一个值。default_metric必需用于查询、脚本和不使用子字段的聚合的默认度量子字段。必须是度量数组中的一个值。
aggregate_metric_double字段支持以下聚合类型
min聚合返回所有min子字段的最小值。max聚合返回所有max子字段的最大值。sum聚合返回所有sum子字段值的总和。value_count聚合返回所有value_count子字段值的总和。avg聚合没有avg子字段avg聚合的结果使用sum和value_count度量来计算。要运行avg聚合字段必须同时包含sum和value_count度量子字段。
如果对aggregate_metric_double字段运行其他任何聚合将失败并出现“不支持的聚合”错误。
此外aggregate_metric_double字段支持以下查询其中它将根据其default_metric子字段的行为充当双精度数
existsrangetermterms
以下是示例请求演示如何创建一个具有aggregate_metric_double字段的索引并添加包含预先聚合数据的文档然后对该字段运行各种聚合
PUT stats-index
{mappings: {properties: {agg_metric: {type: aggregate_metric_double,metrics: [ min, max, sum, value_count ],default_metric: max}}}
}PUT stats-index/_doc/1
{agg_metric: {min: -302.50,max: 702.30,sum: 200.0,value_count: 25}
}PUT stats-index/_doc/2
{agg_metric: {min: -93.00,max: 1702.30,sum: 300.00,value_count: 25}
}对于aggregate_metric_double字段的查询将使用default_metric值。 您可以在agg_metric字段上运行min、max、sum、value_count和avg聚合。以下是一个示例查询请求其中运行了这些聚合并结果基于相关的度量子字段值生成
POST stats-index/_search?size0
{aggs: {metric_min: { min: { field: agg_metric } },metric_max: { max: { field: agg_metric } },metric_value_count: { value_count: { field: agg_metric } },metric_sum: { sum: { field: agg_metric } },metric_avg: { avg: { field: agg_metric } }}
}聚合的结果基于相关的度量子字段值例如min、max、sum、value_count等。
对于aggregate_metric_double字段的查询将使用default_metric的值。以下是一个示例查询请求查询agg_metric字段以获取与default_metric字段此处为max匹配的文档
GET stats-index/_search
{query: {term: {agg_metric: {value: 702.30}}}
}查询结果会返回匹配default_metric字段max值的文档。
别名字段类型 Alias
别名映射定义了索引中字段的替代名称。可以在搜索请求和选定的其他 API如字段能力中使用别名代替目标字段。
PUT trips
{mappings: {properties: {distance: {type: long},route_length_miles: {type: alias,path: distance},transit_mode: {type: keyword}}}
}在上述示例中“route_length_miles” 是 “distance” 字段的别名。在搜索请求中您可以使用 “route_length_miles” 来代替 “distance”。
GET _search
{query: {range : {route_length_miles : {gte : 39}}}
}“route_length_miles” 是别名它实际上代表了 “distance” 字段。别名可以在查询、聚合、排序字段、请求 docvalue_fields、stored_fields、建议和高亮时使用。在访问字段值时脚本也支持别名。请参阅不受支持的 API 部分以了解例外情况。
在搜索请求的某些部分和在请求字段能力时可以提供字段别名的通配符模式。在这些情况下通配符模式将匹配字段别名以及具体字段
GET trips/_field_caps?fieldsroute_*,transit_mode字段别名的目标字段上存在一些限制
目标必须是一个具体字段而不是一个对象或另一个字段别名。在创建别名时目标字段必须存在。如果定义了嵌套对象字段别名必须具有与其目标相同的嵌套范围。此外字段别名只能有一个目标。这意味着不可能使用字段别名在单个子句中查询多个目标字段。
可以通过映射更新将别名更改为引用新目标。已知的限制是如果存储的感知器查询包含字段别名则它们仍将引用其原始目标。更多信息可以在感知器文档中找到。
不支持对字段别名的写入尝试在索引或更新请求中使用别名将导致失败。同样别名不能用作 copy_to 的目标或多字段的一部分。
因为文档源中没有别名名称所以在执行源筛选时不能使用别名。例如以下请求将返回 _source 的空结果
GET /_search
{query : {match_all: {}},_source: route_length_miles
}目前只有搜索和字段能力 API 将接受和解析字段别名。不支持字段别名的其他 API如 term vectors不能与字段别名一起使用。
最后一些查询例如 terms、geo_shape 和 more_like_this允许从索引文档中提取查询信息。由于在提取文档时不支持字段别名指定查找路径的查询部分不能引用别名的字段。
数组 Arrays
在 Elasticsearch 中没有专门的数组数据类型。默认情况下任何字段都可以包含零个或多个值但数组中的所有值必须是相同的数据类型。例如
字符串数组[ “one”, “two” ] 整数数组[ 1, 2 ] 数组中嵌套数组[ 1, [ 2, 3 ]]等同于 [ 1, 2, 3 ] 对象数组[ { “name”: “Mary”, “age”: 12 }, { “name”: “John”, “age”: 10 } ]
对象数组 对象数组的工作方式与您预期的不同无法单独查询数组中的每个对象而不考虑数组中的其他对象。如果需要这样做那么应该使用嵌套数据类型而不是对象数据类型。
这在 Nested 中有更详细的解释。
动态添加字段时数组中的第一个值确定字段类型。所有后续的值必须具有相同的数据类型或者必须至少能够将后续的值强制转换为相同的数据类型。
不支持混合数据类型的数组[ 10, “some string” ]
数组可以包含空值空值可以替换为已配置的 null_value或者完全跳过。空数组 [] 被视为缺失字段即没有值的字段。
要在文档中使用数组无需预先进行任何配置它们可以直接使用
PUT my-index-000001/_doc/1
{message: this document has some arrays...,tags: [ elasticsearch, wow ], lists: [ {name: prog_list,description: programming list},{name: cool_list,description: cool stuff list}]
}第一个文档包含了多个数组字段tags 和 lists。tags 是字符串数组lists 是对象数组。
PUT my-index-000001/_doc/2
{message: no arrays in this document...,tags: elasticsearch,lists: {name: prog_list,description: programming list}
}第二个文档不包含数组但可以索引到相同的字段。
GET my-index-000001/_search
{query: {match: {tags: elasticsearch }}
}查询寻找 tags 字段中的 “elasticsearch” 并匹配了两个文档。
多值字段和倒排索引
所有字段类型默认支持多值字段的事实是 Lucene 的起源。Lucene 被设计为全文搜索引擎。为了能够在大块文本内搜索单词Lucene会将文本标记化为单独的项并将每个项单独添加到倒排索引中。
这意味着即使简单文本字段也必须默认支持多个值。当添加其他数据类型如数字和日期时它们使用与字符串相同的数据结构因此可以自由获得多个值的支持。
二进制 Binary field type 二进制类型接受Base64编码的二进制值作为字符串。默认情况下该字段不会被存储也不可搜索
PUT my-index-000001
{mappings: {properties: {name: {type: text},blob: {type: binary}}}
}PUT my-index-000001/_doc/1
{name: Some binary blob,blob: U29tZSBiaW5hcnkgYmxvYg
}Base64编码的二进制值不能包含嵌套的换行符 \n。
binary字段的参数编辑 binary字段接受以下参数
doc_values
字段是否应以列存储的方式存储在磁盘上以便以后可用于排序、聚合或脚本接受 true 或 false默认值。
store
字段值是否应存储并可从_source字段中单独检索接受 true 或 false默认值。
布尔字段类型 Boolean field type
布尔字段接受JSON中的true和false值但也可以接受被解释为true或false的字符串
false值
false, “false”, “”空字符串
true值
true, “true”
例如
PUT my-index-000001
{mappings: {properties: {is_published: {type: boolean}}}
}POST my-index-000001/_doc/1?refresh
{is_published: true
}GET my-index-000001/_search
{query: {term: {is_published: true}}
}将带有true的文档索引它将被解释为true。
搜索具有JSON true的文档
聚合如terms聚合使用1和0作为键字符串true和false作为key_as_string。在脚本中使用布尔字段时返回true和false
POST my-index-000001/_doc/1?refresh
{is_published: true
}POST my-index-000001/_doc/2?refresh
{is_published: false
}GET my-index-000001/_search
{aggs: {publish_state: {terms: {field: is_published}}},sort: [ is_published ],fields: [{field: weight}],runtime_mappings: {weight: {type: long,script: emit(doc[is_published].value ? 10 : 0)}}
}布尔字段在脚本中使用时返回true和false。
布尔字段的参数 布尔字段接受以下参数 boost 映射字段级别的查询时增强。接受浮点数默认为1.0。 doc_values 字段是否应以列存储的方式存储在磁盘上以便以后可用于排序、聚 合或脚本接受true默认值或false。 index 字段是否应可搜索接受true默认和false。 null_value 接受上面列出的true或false值中的任何一个。该值将替代任何显式的 null值。默认为null这意味着该字段被视为缺失。请注意如果使用 脚本参数则不能设置此参数。 on_script_error 定义如果脚本由脚本参数在索引时引发错误时应该执行什么操作。接受fail默认值它将导致整个文档被拒绝和continue它将在文档的_ignored元数据字段中注册该字段并继续索引。只有在还设置了script字段时才能设置此参数。 script 如果设置了此参数字段将索引由此脚本生成的值而不是直接从源中读取值。如果在输入文档中为此字段设置了值那么将拒绝该文档并显示错误。脚本的格式与其运行时等效版本相同。 store 字段值是否应存储并且是否可以从_source字段中单独检索接受true或false默认值。 meta 关于字段的元数据。
日期字段类型 Date
JSON没有日期数据类型因此Elasticsearch中的日期可以是
包含格式化日期的字符串例如2015-01-01或2015/01/01 12:10:30。 ●表示自纪元以来的毫秒数的数字。 ●表示自纪元以来的秒数配置。 ●自纪元以来的毫秒数值必须为非负数。要表示1970年之前的日期请使用格式化日期。
在内部日期将被转换为协调世界时如果指定了时区并存储为表示自纪元以来的毫秒数的长数字。
日期上的查询在内部转换为对此长表示的范围查询聚合和存储字段的结果将根据与字段关联的日期格式转换回字符串。
日期始终以字符串形式呈现即使它们最初作为JSON文档中的长整数提供。
日期格式可以自定义但如果没有指定格式则使用默认格式
“strict_date_optional_time||epoch_millis”
这意味着它将接受带有可选时间戳的日期符合strict_date_optional_time或毫秒自纪元支持的格式。
例如
PUT my-index-000001
{mappings: {properties: {date: {type: date}}}
}PUT my-index-000001/_doc/1
{ date: 2015-01-01 }PUT my-index-000001/_doc/2
{ date: 2015-01-01T12:10:30Z }PUT my-index-000001/_doc/3
{ date: 1420070400001 }GET my-index-000001/_search
{sort: { date: asc }
}日期字段使用默认格式。 此文档使用普通日期。 此文档包含时间。 此文档使用自纪元以来的毫秒数。 请注意返回的排序值都以自纪元以来的毫秒数为单位。
日期将接受带有小数点的数字如{“date”: 1618249875.123456}但有一些情况70085下会丢失这些日期的精度因此应避免使用它们。
多日期格式 可以通过在它们之间使用||作为分隔符来指定多个格式。将逐个尝试每个格式直到找到匹配的格式。将使用第一个格式将自纪元以来的毫秒数值转换回字符串。
PUT my-index-000001
{mappings: {properties: {date: {type: date,format: yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis}}}
}日期字段的参数 日期字段接受以下参数 boost 映射字段级别的查询时增强。接受浮点数默认为1.0。 doc_values 字段是否应以列存储的方式存储在磁盘上以便以后可用于排序、聚合或脚本接受true默认值或false。 format 可以解析的日期格式。默认为strict_date_optional_time||epoch_millis。 locale 解析日期时要使用的区域设置因为不同语言的月份名称和/或缩写不同。默认是ROOT区域设置。 ignore_malformed 如果为true则会忽略格式不正确的数字。如果为false默认值则格式不正确的数字会引发异常并拒绝整个文档。请注意如果使用脚本参数无法设置此参数。 index 字段是否应可搜索接受true默认和false。 null_value 接受任何配置格式的日期值以替代任何明确的null值。默认为null这意味着该字段被视为缺失。请注意如果使用脚本参数则无法设置此参数。 on_script_error 定义如果由脚本参数定义的脚本在索引时引发错误时应执行的操作。接受fail默认值它将导致整个文档被拒绝以及continue它将在文档的_ignored元数据字段中注册字段并继续索引。只有在还设置了script字段时才能设置此参数。 script 如果设置了此参数字段将索引由此脚本生成的值而不是直接从源中读取值。如果在输入文档中为此字段设置了值那么将拒绝该文档并显示错误。脚本的格式与其运行时等效版本相同应该发出长整数时间戳。 store 字段值是否应存储并且是否可以从_source字段中单独检索接受true或false默认值。 meta 关于字段的元数据。
纪元秒 如果需要将日期发送为自纪元以来的秒数请确保格式中列出了epoch_second
PUT my-index-000001
{mappings: {properties: {date: {type: date,format: strict_date_optional_time||epoch_second}}}
}PUT my-index-000001/_doc/example?refresh
{ date: 1618321898 }POST my-index-000001/_search
{fields: [ {field: date}],_source: false
}这将回复一个类似的日期
{hits: {hits: [{_id: example,_index: my-index-000001,_type: _doc,_score: 1.0,fields: {date: [2021-04-13T13:51:38.000Z]}}]}
}日期纳秒字段类型 Date nanoseconds field type
此数据类型是日期数据类型的一个补充。但两者之间有一个重要的区别。现有的日期数据类型以毫秒分辨率存储日期。日期纳秒数据类型以纳秒分辨率存储日期这限制了日期范围大约从1970年到2262年因为日期仍然存储为表示自纪元以来的纳秒的长整数。
日期的纳秒上的查询在内部转换为对此长整数表示的范围查询聚合和存储字段的结果将根据与字段关联的日期格式转换为字符串。
日期格式可以自定义但如果没有指定格式则使用默认格式
“strict_date_optional_time_nanos||epoch_millis”
例如
PUT my-index-000001?include_type_nametrue
{mappings: {_doc: {properties: {date: {type: date_nanos}}}}
}PUT my-index-000001/_bulk?refresh
{ index : { _id : 1 } }
{ date: 2015-01-01 }
{ index : { _id : 2 } }
{ date: 2015-01-01T12:10:30.123456789Z }
{ index : { _id : 3 } }
{ date: 1420070400000 }GET my-index-000001/_search
{sort: { date: asc},runtime_mappings: {date_has_nanos: {type: boolean,script: emit(doc[date].value.nano ! 0)}},fields: [{field: date,format: strict_date_optional_time_nanos},{field: date_has_nanos}]
}日期字段使用默认格式。
此文档使用普通日期。
此文档包含时间。
此文档使用自纪元以来的毫秒数。
请注意返回的排序值都以自纪元以来的纳秒为单位。
在脚本中使用 .nano 可以返回日期的纳秒组件。
您可以在使用字段参数提取数据时指定格式。使用strict_date_optional_time_nanos否则会得到一个四舍五入的结果。
您还可以指定用||分隔的多个日期格式。与日期字段一样可以使用相同的映射参数。
日期纳秒将接受带有小数点的数字例如{“date”: 1618249875.123456}但在某些情况下#70085会丢失这些日期的精度因此应避免使用它们。
限制 即使使用date_nanos字段聚合仍然以毫秒分辨率进行这一限制也影响到了转换。
密集向量字段类型 Dense vector field type
密集向量字段存储浮点值的密集向量。向量中可以包含的维数不应超过2048。密集向量字段是单值字段。
密集向量字段不支持查询、排序或聚合。它们只能通过专用的向量函数在脚本中访问。
您可以将密集向量索引为浮点数数组。
PUT my-index-000001
{mappings: {properties: {my_vector: {type: dense_vector,dims: 3},my_text : {type : keyword}}}
}PUT my-index-000001/_doc/1
{my_text : text1,my_vector : [0.5, 10, 6]
}PUT my-index-000001/_doc/2
{my_text : text2,my_vector : [-0.5, 10, 10]
}dims - 向量中的维数必填参数。
展平字段类型 Flattened field type
默认情况下对象中的每个子字段都会被单独映射和索引。如果子字段的名称或类型事先不知道那么它们会动态映射。
flattened 类型提供了另一种方法它会将整个对象映射为单个字段。给定一个对象flattened 映射将解析出其叶子值并将它们索引为关键字。然后可以通过简单的查询和聚合搜索对象的内容。
这种数据类型对于索引具有大量或未知数量唯一键的对象非常有用。整个 JSON 对象只创建一个字段映射这有助于防止映射爆炸导致具有太多不同字段映射。
另一方面展平的对象字段在搜索功能方面存在一种权衡。只允许基本查询不支持数值范围查询或高亮显示。更多关于限制的信息可以在支持的操作部分找到。
展平映射类型不应用于索引所有文档内容因为它将所有值视为关键字不提供完整的搜索功能。在大多数情况下每个子字段都有自己的映射条目的默认方法运行良好。
可以创建展平的对象字段如下
PUT bug_reports
{mappings: {properties: {title: {type: text},labels: {type: flattened}}}
}POST bug_reports/_doc/1
{title: Results are not sorted correctly.,labels: {priority: urgent,release: [v1.2.5, v1.3.0],timestamp: {created: 1541458026,closed: 1541457010}}
}在索引期间将为 JSON 对象中的每个叶子值创建标记。这些值将作为字符串关键字进行索引而不会进行分析或对数字或日期进行特殊处理。
查询顶级展平字段将搜索对象中的所有叶子值
POST bug_reports/_search
{query: {term: {labels: urgent}}
}要在展平对象中的特定键上查询使用对象点表示法
POST bug_reports/_search
{query: {term: {labels.release: v1.3.0}}
}支持的操作 由于展平字段索引值的方式相似展平字段与关键字字段共享许多相同的映射和搜索功能。
目前展平对象字段可与以下查询类型一起使用
term、terms 和 terms_setprefixrangematch 和 multi_matchquery_string 和 simple_query_stringexists
在查询时无法使用通配符引用字段键如 { “term”: {“labels.time*”: 1541457010}}。请注意所有查询包括范围查询都将值视为字符串关键字。展平字段不支持高亮显示。
可以对展平的对象字段进行排序并执行类似关键字的简单聚合例如 terms。与查询一样没有为数值提供特殊支持JSON 对象中的所有值都被视为关键字进行比较。
目前展平的对象字段无法存储。无法在映射中指定 store 参数。
检索展平字段的值 可以使用 fields 参数检索字段值和具体子字段。由于展平字段将一个整个对象映射为单个字段响应包含来自 _source 的不经修改的结构。
但是可以通过在请求中明确指定它们来获取单个子字段。这仅适用于具体路径而不能使用通配符
PUT my-index-000001
{mappings: {properties: {flattened_field: {type: flattened}}}
}PUT my-index-000001/_doc/1?refreshtrue
{flattened_field : {subfield : value}
}POST my-index-000001/_search
{fields: [flattened_field.subfield],_source: false
}您还可以使用 Painless 脚本从展平字段的子字段中检索值。在 Painless 脚本中不要使用 doc[‘field_name’].value而要使用 doc[‘field_name.sub-field_name’].value。例如如果映射中包含两个字段其中一个是展平类型
PUT my-index-000001
{mappings: {properties: {title: {type: text},labels: {type: flattened}}}
}为映射的字段编制一些包含标签字段的文档。标签字段具有三个子字段
POST /my-index-000001/_bulk?refresh
{index:{}}
{title:Something really urgent,labels:{priority:urgent,release:[v1.2.5,v1.3.0],timestamp:{created:1541458026,地理点字段类型 Geopoint field type
地理点字段geo_point接受纬度-经度对可用于以下用途
查找位于边界框内、距中心点一定距离内、位于多边形内或在geo_shape查询内的地理点。按地理或距离从中心点聚合文档。将距离集成到文档的相关性评分中。按距离对文档进行排序。
地理点可以以以下五种方式指定如下所示
PUT my-index-000001
{mappings: {properties: {location: {type: geo_point}}}
}PUT my-index-000001/_doc/1
{text: 地理点作为对象,location: { lat: 41.12,lon: -71.34}
}PUT my-index-000001/_doc/2
{text: 地理点作为字符串,location: 41.12,-71.34
}PUT my-index-000001/_doc/3
{text: 地理点作为地理哈希,location: drm3btev3e86
}PUT my-index-000001/_doc/4
{text: 地理点作为数组,location: [ -71.34, 41.12 ]
}PUT my-index-000001/_doc/5
{text: 地理点作为WKT POINT原语,location : POINT (-71.34 41.12)
}GET my-index-000001/_search
{query: {geo_bounding_box: { location: {top_left: {lat: 42,lon: -72},bottom_right: {lat: 40,lon: -74}}}}
}以对象形式表示的地理点带有lat和lon键。以字符串形式表示的地理点格式为纬度,经度。以地理哈希形式表示的地理点。以数组形式表示的地理点格式为[经度,纬度]。以WKT POINT原语形式表示的地理点格式为POINT(经度 纬度)。
重要提示 请注意字符串形式的地理点按纬度,经度排序而数组形式的地理点按相反的顺序即经度,纬度。
初始情况下纬度,经度形式同时用于数组和字符串但很早就更改为符合GeoJSON使用的格式。
注意 地理哈希geohash是将纬度和经度的位用base32编码字符串交错在一起而成。地理哈希中的每个字符为精度添加额外的5位。因此哈希越长精度越高。对于索引目的地理哈希转换为纬度-经度对。在此过程中仅使用前12个字符因此在地理哈希中指定超过12个字符不会增加精度。这12个字符提供60位精度可以将潜在的误差降至不到2厘米。
地理点字段的参数 ignore_malformed如果设置为true将忽略格式错误的地理点。如果设置为false默认值则格式错误的地理点将引发异常并拒绝整个文档。地理点被视为格式错误如果其纬度范围超出-90 纬度 90或者经度范围超出-180 经度 180。请注意如果使用了脚本参数无法设置此选项。 ignore_z_value如果设置为true默认值将接受三维点存储在源中但仅索引纬度和经度值第三维度将被忽略。如果设置为false包含除纬度和经度以外的任何值的地理点将引发异常并拒绝整个文档。请注意如果使用了脚本参数无法设置此选项。 index是否应将字段设置为可搜索接受true默认值和false。 null_value接受用于替换任何显式空值的地理点值。默认值为null表示该字段将被视为缺失。请注意如果使用了脚本参数无法设置此选项。 on_script_error定义如果脚本参数定义的脚本在索引时引发错误应该执行的操作。接受fail默认值它将导致整个文档被拒绝和continue它将将字段注册在文档的_ignored元数据字段中并继续索引。此参数只能在同时设置脚本字段时才能设置。 script如果设置了此参数字段将索引由该脚本生成的值而不是直接从源中读取值。如果在输入文档上为此字段设置了值文档将被拒绝并显示错误。脚本的格式与其运行时等效项相同应以纬度、经度双精度值对的形式发出点。
在脚本中使用地理点
在脚本中访问地理点的值时该值以GeoPoint对象的形式返回允许访问.lat和.lon值。
示例
def geopoint doc[location].value;
def lat geopoint.lat;
def lon geopoint.lon;出于性能原因最好直接访问lat/lon值如下所示
def lat doc[location].lat;
def lon doc[location].lon;地理形状字段类型 Geo Shape Field Type
地理形状字段类型Geo Shape Field Type是 Elasticsearch 中用于索引和搜索任意地理形状如矩形和多边形的数据类型。它应该在要索引的数据或要执行的查询中包含不仅仅是点的形状时使用。你可以使用地理形状查询geo_shape query来查询使用此类型的文档。
地理形状字段可以使用不同的地理树编码方法BKD编码或前缀树编码来进行编码。默认情况下Elasticsearch将地理形状的值编码为BKD树。如果不指定以下映射选项则将使用BKD编码
distance_error_pctpoints_onlyprecisionstrategytree_levelstree
如果指定了上述选项之一字段将使用前缀树编码。前缀树编码已被弃用。
以下是地理形状字段的映射选项 tree已弃用不再使用。前缀树的名称可选值为 “geohash”用于Geohash前缀树和 “quadtree”用于Quad前缀树。 precision已弃用不再使用。此参数可用来设置tree_levels参数的合适值该值指定所需的精度Elasticsearch将计算出tree_levels参数的最佳值以满足所需精度。此参数应该是一个数字后面可以跟一个可选的距离单位如 “m”米、“km”千米、“mi”英里等。 tree_levels已弃用不再使用。前缀树要使用的最大层级数可用来控制形状表示的精度以及索引的术语数。默认值取决于所选的前缀树实现。如果用户了解底层实现的工作原理可以使用此参数。然而Elasticsearch在内部仅使用tree_levels参数并且即使使用precision参数也是通过映射API返回tree_levels参数。 strategy已弃用不再使用。该参数定义了索引和搜索时如何表示形状的方法。建议让Elasticsearch自动设置此参数。有两种可用的策略recursive 和 term。Recursive 和 Term策略已弃用将在将来的版本中移除。虽然它们仍然可用Term策略仅支持点类型points_only参数将自动设置为true而Recursive策略支持所有形状类型。同时对于这两种策略Elasticsearch建议使用向量编码的方法Vector Indexing。 distance_error_pct已弃用不再使用。用于指示前缀树在精度方面应具有多大程度的准确性。默认值为0.0252.5%最大支持值为0.5。注意如果显式定义了精度或tree_level则此值将默认为0。这可以导致对具有低误差的高分辨率形状例如具有小于0.001误差的1米大的形状而言内存使用量显著增加。为了提高索引性能以牺牲查询准确性为代价可以显式定义tree_level或precision以及合理的distance_error_pct但要注意大形状会有更多的误报。 orientation可选。字段的WKT多边形的默认方向。此参数设置并返回RIGHT顺时针或LEFT逆时针值。但可以以多种方式指定任一值。 要设置RIGHT请使用以下参数或其大写变体 rightcounterclockwiseccw 要设置LEFT请使用以下参数或其大写变体 leftclockwisecw points_only已弃用不再使用。将此选项设置为true默认值为false会配置地理形状字段类型仅用于点形状注意不支持多点。这会优化当只有点会被索引时的索引和搜索性能例如在已知只有点将被索引时可以提高geohash和quadtree的性能
。目前不能对geo_point字段类型执行geo_shape查询。此选项弥合了这一差距通过改善点字段上的性能使得在只有点的字段上执行geo_shape查询变得最佳。 ignore_malformed如果为true则忽略格式错误的GeoJSON或WKT形状。如果为false默认值格式错误的GeoJSON和WKT形状将引发异常并拒绝整个文档。 ignore_z_value如果为true默认值将接受包含三维点存储在源中但仅索引纬度和经度值忽略第三维度。如果为false包含多于纬度和经度两个维度值的地理点会引发异常并拒绝整个文档。 coerce如果为true将自动封闭多边形中的未封闭线性环linear rings。
地理形状字段类型的索引方法地理形状类型通过将形状分解为三角形网格并将每个三角形作为BKD树中的7维点进行索引。这提供了接近完美的空间分辨率精度高达1e-7小数度因为所有空间关系都是使用原始形状的编码向量表示来计算的而不是使用前缀树编码使用的栅格格网表示。网格化器的性能主要取决于定义多边形/多多边形的顶点数。虽然这是默认的索引技术但仍然可以通过根据适当的映射选项来设置tree或strategy参数来使用前缀树编码。注意这些参数现在已被弃用将在将来的版本中移除。
重要说明
包含关系查询 - 当使用新的默认向量索引策略时定义为包含关系的地理形状查询contains仅支持在ElasticSearch 7.5.0或更高版本创建的索引。
前缀树为了有效地在倒排索引中表示形状使用前缀树的实现将形状转换为表示网格方格的一系列哈希值通常称为“栅格”。前缀树使用多个网格层每个层的精度逐渐增加以表示地球。这可以被视为在更高的缩放级别提高地图或图像的详细程度。由于这种方法导致了带有索引形状的精度问题因此已经弃用而向量编码方法见索引方法已取而代之。
提供多个前缀树实现 GeohashPrefixTree使用Geohash表示网格方格。Geohash是基于经度和纬度位交错的base32编码字符串。因此哈希值越长精度越高。每个添加到Geohash的字符代表另一个树层并增加5位精度。Geohash表示一个矩形区域有32个子矩形。Elasticsearch中Geohash的最大层级数是24默认值是9。 QuadPrefixTree使用Quadtree表示网格方格。与Geohash类似Quadtree将纬度和经度的位数交错生成一个位集。Quadtree中的一个树层表示该位集中的2位分别用于每个坐标。Elasticsearch中Quadtree的最大层级数是29默认值是21。
空间策略已弃用不再使用。所选的索引实现依赖于SpatialStrategy以选择如何分解形状作为网格方格或网格方格三角网格。每个策略回答以下问题
可以索引哪种形状可以使用哪些查询操作和形状是否支持一个字段中的多个形状
提供以下策略实现以及相应的功能 Recursive策略支持所有形状支持的查询操作包括INTERSECTS、DISJOINT、WITHIN、CONTAINS。允许一个字段中包含多个形状。 Term策略支持点支持的查询操作包括INTERSECTS。允许一个字段中包含多个形状。在使用Term策略时points_only参数会自动设置为true。
精度Recursive策略和Term策略不能提供100%的准确性具体取决于如何配置它们可能会返回INTERSECTS、WITHIN和CONTAINS查询的一些误报以及DISJOINT查询的一些漏报。为了减轻这一问题重要的是选择tree_levels参数的适当值并相应地调整期望。例如一个点可能接近特定网格单元的边界因此可能与仅与其相邻的网格单元匹配的查询不匹配尽管该形状非常接近该点。
示例
以下是一个示例演示如何映射一个具有地理形状字段的索引
PUT /example
{mappings: {properties: {location: {type: geo_shape}}}
}在上述映射中将location字段映射为geo_shape类型使用默认的向量实现提供了大约1e-7小数度的精度。
性能注意事项
使用前缀树的性能考虑使用前缀树时Elasticsearch使用树中的路径作为倒排索引中的术语。层级越高因此精度越高
生成的术语就越多。当然计算这些术语将它们保存在内存中并将它们存储在磁盘上都是有代价的。特别是对于更高级别的树即使有适度的数据量索引可能会变得非常大。此外特征的大小也很重要。大型复杂多边形在更高的树层级时会占用大量空间。哪种设置适合取决于用例。一般来说需要在准确性、索引大小和查询性能之间进行权衡。
Elasticsearch中两种实现的默认值都是在赤道上约50米的适度精度的折衷方案。这允许索引数千万个形状而相对于输入大小来说不会过分膨胀索引的大小。
在使用前缀树实现的地理形状上执行geo_shape查询如果search.allow_expensive_queries设置为false查询将不会被执行。
输入结构
形状可以使用GeoJSON或Well-Known TextWKT格式表示。以下表格提供了GeoJSON和WKT到Elasticsearch类型的映射
GeoJSON类型 WKT类型 Elasticsearch类型 描述 Point POINT point 单个地理坐标。注意Elasticsearch仅使用WGS-84坐标。 LineString LINESTRING linestring 由两个或多个点给定的任意线。 Polygon POLYGON polygon 由点的列表列表定义的多边形。每个外部列表中的第一个点和最后一个点必须相同多边形必须封闭因此需要n 1个顶点来创建一个n边的多边形最少需要4个顶点。 MultiPoint MULTIPOINT multipoint 一组不相连但可能相关的点。 MultiLineString MULTILINESTRING multilinestring 一组单独的线串。 MultiPolygon MULTIPOLYGON multipolygon 一组单独的多边形。 GeometryCollection GEOMETRYCOLLECTION geometrycollection 类似于multi*形状的GeoJSON形状不同之处在于多个类型可以共存例如一个点和一个线串。 N/A BBOX envelope 由指定的仅有左上角和右下角点而没有其他点的矩形bounding rectangle。 N/A N/A circle 由中心点和半径默认为METERS指定的圆。
对于所有类型坐标数组中的正确坐标顺序是经度、纬度X、Y。这与许多地理空间API例如Google Maps通常使用的纬度、经度Y、X不同。
点
点是单个地理坐标例如建筑物的位置或智能手机的Geolocation API给出的当前位置。以下是GeoJSON中点的示例
POST /example/_doc
{location : {type : Point,coordinates : [-77.03653, 38.897676]}
}以下是WKT中点的示例
POST /example/_doc
{location : POINT (-77.03653 38.897676)
}线串
线串由两个或多个位置的数组定义。通过只指定两个点线串将表示一条直线。指定两个以上的点会创建一条任意路径。以下是GeoJSON中线串的示例
POST /example/_doc
{location : {type : LineString,coordinates : [[-77.03653, 38.897676], [-77.009051, 38.889939]]}
}以下是WKT中线串的示例
POST /example/_doc
{location : LINESTRING (-77.03653 38.897676, -77.009051 38.889939)
}上述线串将从白宫出发绘制一条直线到美国国会大厦。
多边形
多边形由点列表的列表定义。每个外部列表中的第一个点和最后一个点必须相同多边形必须封闭。以下是GeoJSON中多边形的示例
POST /example/_doc
{location : {type : Polygon,coordinates : [[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]]}
}以下是WKT中多边形的示例
POST /example/_doc
{location : POLYGON ((100 0, 101 0, 101 1, 100 1, 100 0))
}上述多边形定义了一个简单的矩形坐标范围从经度100.0到101.0纬度从0.0到1.0。
多点
多点是由一组不相连但可能相关的点组成的。每个点都有一个坐标。以下是GeoJSON中多点的示例
POST /example/_doc
{location : {type : MultiPoint,coordinates : [[100.0, 0.0], [101.0, 1.0]]}
}以下是WKT中多点的示例
POST /example/_doc
{location : MULTIPOINT (100 0, 101 1)
}上述示例包含两个点。
多线串
多线串是一组单独的线串每个线串都由点的数组定义。以下是GeoJSON中多线串的示例
POST /example/_doc
{location : {type : MultiLineString,coordinates : [[ [-77.03653, 38.897676], [-77.009051, 38.889939] ],[ [-77.095158, 38.864666], [-77.016683, 38.915387] ]]}
}以下是WKT中多线串的示例
POST /example/_doc
{location : MULTILINESTRING ((-77.03653 38.897676, -77.009051 38.889939), (-77.095158 38.864666, -77.016683 38.915387))
}上述示例包含两个线串每个线串都是一条路径。
多多边形
多多边形是一组单独的多边形每个多边形都由点列表的列表定义。以下是GeoJSON中多多边形的示例
POST /example/_doc
{location : {type : MultiPolygon,coordinates : [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]]]}
}以下是WKT中多多边形的示例
POST /example/_doc
{location : MULTIPOLYGON (((102 2, 103 2, 103 3, 102 3, 102 2)), ((100 0, 101 0, 101 1, 100 1, 100 0))
}上述示例包含两个多边形每个多边形都是一个矩形。
空间策略
空间策略定义如何在倒排索引中表示形状。每个策略具有特定的特征集和适用性。空间策略不影响查询或存储多边形的形状本身。两个策略的区别是如何分解形状并如何在倒排索引中存储特征。两个主要策略实现是 Recursive策略支持所有形状支持的查询操作包括INTERSECTS、DISJOINT、WITHIN、CONTAINS。允许一个字段中包含多个形状。 Term策略支持点支持的查询操作包括INTERSECTS。允许一个字段中包含多个形状。
前缀树策略已弃用前缀树策略用于使用前缀树作为索引形状表示的策略。前缀树策略已弃用不再使用。
示例
以下是使用Recursive策略的示例
PUT /example
{mappings: {properties: {location: {type: geo_shape,strategy: recursive}}}
}在上述示例中location字段使用了Recursive策略。
以下是使用Term策略的示例
PUT /example
{mappings: {properties: {location: {type: geo_shape,strategy: term}}}
}在上述示例中location字段使用了Term策略。
前缀树策略已弃用不再使用。
查询方法
地理形状字段可以使用geo_shape查询来执行各种地理查询操作如INTERSECTS、DISJOINT、WITHIN、CONTAINS等。下面是一些常见的地理查询示例
使用INTERSECTS查询来查找与指定形状相交的文档
{query: {geo_shape: {location: {shape: {type: Polygon,coordinates: [[[-77.03653, 38.897676],[-77.009051, 38.889939],[-77.006438, 38.893371],[-77.03653, 38.897676]]]},relation: intersects}}}
}使用DISJOINT查询来查找与指定形状不相交的文档
{query: {geo_shape: {location: {shape: {type: Polygon,coordinates: [[[-77.03653, 38.897676],[-77.009051, 38.889939],[-77.006438, 38.893371],[-77.03653, 38.897676]]]},relation: disjoint}}}
}使用WITHIN查询来查找包含在指定形状内的文档
{query: {geo_shape: {location: {shape: {type: Polygon,coordinates: [[[-77.03653, 38.897676],[-77.009051, 38.889939],[-77.006438, 38.893371],[-77.03653, 38.897676]]]},relation: within}}}
}使用CONTAINS查询来查找包含指定形状的文档
{query: {geo_shape: {location: {shape: {type: Point,coordinates: [-77.022731, 38.897705]},relation: contains}}}
}这些示例只是一些基本的查询操作。您可以根据需要组合这些操作以实现更复杂的地理查询。请注意性能会受到形状的复杂性、索引设置和查询条件的影响因此需要根据具体情况进行调整。
直方图字段类型 Histogram
Histogram字段是一种用于存储预聚合的数值数据表示直方图的字段类型。直方图数据由两个成对的数组定义
values 数组包含双精度浮点数表示直方图的桶buckets。这些值必须按升序提供。counts 数组包含整数表示落入每个桶中的值的数量。这些数量必须是正数或零。
由于values数组中的元素对应于counts数组中相同位置的元素这两个数组必须具有相同的长度。
一个直方图字段只能存储文档中的一个值和计数数组对。不支持嵌套数组。直方图字段不支持排序。
参数
time_series_metric可选字符串标记字段是否为时间序列度量。对于直方图字段此参数接受值 “histogram”。
使用 直方图字段主要用于聚合。为了更容易进行聚合直方图字段数据存储为二进制文档值doc values而不是索引。其字节大小最多为 13 * numValues其中 numValues 是提供的数组的长度。
因为数据不被索引您只能使用直方图字段进行以下聚合和查询
最小值聚合min aggregation最大值聚合max aggregation求和聚合sum aggregation计数聚合value_count aggregation平均值聚合avg aggregation百分位数聚合percentiles aggregation百分位数排名聚合percentile ranks aggregation箱线图聚合boxplot aggregation直方图聚合histogram aggregation范围聚合range aggregation存在查询exists query
构建直方图 当将直方图作为聚合的一部分时结果的准确性将取决于构建直方图的方式。重要的是考虑将用于构建直方图的百分位数聚合模式。一些可能性包括
对于T-Digest模式values数组表示均值中心位置counts数组表示归属于每个中心的值的数量。如果算法已经开始近似百分位数那么这种不准确性会传递到直方图中。对于高动态范围HDR直方图模式values数组表示每个桶间隔的固定上限counts数组表示归属于每个间隔的值的数量。这个实现维护了一个固定的最坏情况百分比误差指定为有效数字的数量因此在生成直方图时使用的值将是您在聚合时能够实现的最大精度。
直方图字段是“算法不可知”的不存储特定于T-Digest或HDRHistogram的数据。这意味着字段在技术上可以使用任一算法进行聚合但实际上用户应该选择一种算法并以该方式索引数据例如T-Digest的中心点或HDRHistogram的间隔以确保最佳准确性。
示例 以下是一个创建索引和存储直方图字段的示例
创建一个新索引包括两个字段映射
my_histogram用于存储百分位数数据的直方图字段my_text用于存储直方图标题的关键字字段
PUT my-index-000001
{mappings: {properties: {my_histogram: {type: histogram},my_text: {type: keyword}}}
}存储两个直方图的预聚合数据分别为 histogram_1 和 histogram_2
PUT my-index-000001/_doc/1
{my_text: histogram_1,my_histogram: {values: [0.1, 0.2, 0.3, 0.4, 0.5], counts: [3, 7, 23, 12, 6] }
}PUT my-index-000001/_doc/2
{my_text: histogram_2,my_histogram: {values: [0.1, 0.25, 0.35, 0.4, 0.45, 0.5], counts: [8, 17, 8, 7, 6, 2] }
}ip字段类型 IP
ip字段类型是用于索引和存储IPv4或IPv6地址的字段类型。
示例创建一个包含ip字段的索引
PUT my-index-000001
{mappings: {properties: {ip_addr: {type: ip}}}
}然后存储一个IPv4地址的文档
PUT my-index-000001/_doc/1
{ip_addr: 192.168.1.1
}要查询ip字段您可以使用CIDR表示法例如
GET my-index-000001/_search
{query: {term: {ip_addr: 192.168.0.0/16}}
}或者如果您要查询IPv6地址需要注意冒号是查询字符串查询的特殊字符因此IPv6地址需要转义。最简单的方法是在搜索的值周围加上引号
GET my-index-000001/_search
{query: {query_string: {query: ip_addr:\2001:db8::/48\}}
}ip字段类型接受以下参数
boost映射字段级别的查询时间加权。接受浮点数默认为1.0。doc_values指定字段是否以列式存储方式存储在磁盘上以便以后用于排序、聚合或脚本。接受true默认值或false。ignore_malformed如果为true则忽略格式错误的IP地址。如果为false默认值则格式错误的IP地址会引发异常并拒绝整个文档。注意如果使用script参数则无法设置此参数。index指定字段是否可搜索。接受true默认值和false。null_value接受用于替代任何明确的空值的IPv4或IPv6值。默认为null这意味着该字段将被视为丢失。请注意如果使用script参数则无法设置此参数。on_script_error定义如果script参数定义的脚本在索引时引发错误时应执行的操作。接受reject默认值这将导致整个文档被拒绝和ignore这将在文档的_ignored元数据字段中注册字段并继续索引。只能在设置script字段时才能设置此参数。script如果设置了此参数字段将索引由该脚本生成的值而不是直接从源中读取值。如果在输入文档中设置了此字段的值那么将拒绝文档并生成错误。脚本采用与其运行时等效的格式应生成包含IPv4或IPv6格式地址的字符串。store指定字段值是否应与_source字段分开存储和检索。接受true或false默认值。time_series_dimension技术预览功能用于内部用途由Elastic公司使用。
父子关系字段类型 join
join字段类型是Elasticsearch中的一种特殊字段类型用于在同一索引的文档之间创建父子关系。关系部分定义了文档内的一组可能的关系每个关系都包括一个父名称和一个子名称。
在Elasticsearch中不建议使用多级关系来复制关系模型。每个关系级别在查询时会增加内存和计算方面的开销。为了获得更好的搜索性能建议对数据进行去规范化denormalize。
父子关系可以如下所示定义
PUT my-index-000001
{mappings: {properties: {my_id: {type: keyword},my_join_field: { type: join,relations: {question: answer }}}}
}在上述示例中创建了一个名为my_join_field的join字段定义了一个父关系 “question” 和一个子关系 “answer”。
要索引具有关系的文档必须在文档的源中提供关系的名称以及可选的父文档。例如以下示例在 “question” 上下文中创建了两个父文档
PUT my-index-000001/_doc/1?refresh
{my_id: 1,text: This is a question,my_join_field: {name: question }
}PUT my-index-000001/_doc/2?refresh
{my_id: 2,text: This is another question,my_join_field: {name: question}
}父文档的索引时您可以选择仅指定关系的名称作为一种快捷方式而无需将其封装在正常的对象表示法中
PUT my-index-000001/_doc/1?refresh
{my_id: 1,text: This is a question,my_join_field: question
}PUT my-index-000001/_doc/2?refresh
{my_id: 2,text: This is another question,my_join_field: question
}当索引子文档时必须在_source中添加关系的名称以及文档的父ID。为了正确建立父子关系子文档必须路由到其更大的父文档上因此必须使用正确的路由值。以下示例展示了如何索引两个子文档
PUT my-index-000001/_doc/3?routing1refresh
{my_id: 3,text: This is an answer,my_join_field: {name: answer, parent: 1 }
}PUT my-index-000001/_doc/4?routing1refresh
{my_id: 4,text: This is another answer,my_join_field: {name: answer,parent: 1}
}要建立父子关系子文档必须与其更大的父文档在同一个分片上。因此在获取、删除或更新子文档时必须提供相同的路由值。
join字段使用全局序数来加速关联操作。全局序数需要在分片发生任何更改后进行重建。全局序数默认会急切地进行构建如果索引发生更改join字段的全局序数将作为刷新的一部分重建。然而在大多数情况下这是正确的权衡否则当首次使用父子关联查询或聚合时将重建join字段的全局序数。这可能会为用户引入显著的延迟通常会更糟因为在多个写操作发生时可能会尝试在单个刷新间隔内重建多个join字段的全局序数。
如果join字段很少使用并且写操作频繁发生可能有意义禁用急切加载
PUT my-index-000001
{mappings: {properties: {my_join_field: {type: join,relations: {question: answer},eager_global_ordinals: false}}}
}上述设置允许禁用急切加载从而在索引变化时不重建join字段的全局序数。
join字段允许定义多个子文档作为单个父文档的子文档。它还允许定义多个父文档关系但需要确保它们都在相同的分片上。
多级父子关系存在但不建议使用多级关系来复制关系数据库模型。每个关系级别会增加查询时的内存和计算开销。为了获得更好的搜索性能建议对数据进行去规范化。
关键字类型 Keyword type family
关键字类型家族包括以下字段类型
keyword用于结构化内容如ID、电子邮件地址、主机名、状态码、邮政编码或标签。constant_keyword针对始终包含相同值的关键字字段。wildcard用于非结构化的机器生成内容该通配符类型经过优化适用于值较大或基数较高的字段。
关键字字段通常用于排序、聚合和术语级别查询如term查询。避免将关键字字段用于全文搜索请使用text字段类型代替。
关键字字段类型示例
以下是一个基本关键字字段的映射示例
PUT my-index-000001
{mappings: {properties: {tags: {type: keyword}}}
}映射数字标识符
并非所有数字数据都应映射为数字字段数据类型。Elasticsearch会为数字字段如整数或长整数进行范围查询进行优化。但是关键字字段更适用于术语和其他术语级别查询。
例如ISBN或产品ID等标识符很少用于范围查询但通常使用术语级别查询来检索它们。如果符合以下条件可以考虑将数字标识符映射为关键字
没有计划使用范围查询搜索标识符数据。快速检索很重要。关键字字段上的术语查询通常比数字字段上的术语查询更快。
如果不确定要使用哪种字段类型可以使用多字段将数据同时映射为关键字和数字数据类型。
基本关键字字段的参数
关键字字段接受以下参数
boost字段级别的查询时间加权。接受浮点数默认为1.0。doc_values字段是否以列存储方式存储在磁盘上以便以后用于排序、聚合或脚本。接受true默认或false。eager_global_ordinals是否在刷新时急切加载全局序数。接受true或false默认。在经常用于术语聚合的字段上启用此选项是个好主意。fields多字段允许相同的字符串值以不同方式进行多次索引以用于不同目的例如一个字段用于搜索多字段用于排序和聚合。ignore_above不要索引任何长于此值的字符串。默认为2147483647以便接受所有值。但请注意默认的动态映射规则通过设置ignore_above: 256创建一个子关键字字段以覆盖此默认值。index字段是否可搜索接受true默认或false。index_options为了评分目的应存储在索引中的信息是什么。默认为docs但还可以设置为freqs以在计算分数时考虑词项频率。meta关于字段的元数据。norms在评分查询时是否应考虑字段长度。接受true或false默认。null_value接受字符串值用于替代任何显式的null值。默认为null这意味着将字段视为缺失。请注意如果使用了脚本值则无法设置此值。on_script_error在索引时由脚本参数定义的脚本引发错误时应采取的措施。接受fail默认值它将导致整个文档被拒绝以及continue它将在文档的_ignored元数据字段中注册该字段并继续索引。只有在设置了脚本字段时才能设置此参数。script如果设置了此参数字段将索引由此脚本生成的值而不是直接从源中读取值。如果在输入文档上设置了此字段的值那么该文档将被拒绝并显示错误。脚本采用与运行时等效项相同的格式。脚本生成的值将按通常方式进行规范化并且如果它们的长度超过了ignore_above上设置的值将被忽略。store字段值是否应单独存储和检索而不与_source字段分开。接受true或false默认。similarity应使用哪种评分算法或相似度。默认为BM25。normalizer在索引之前如何预处理关键字。默认为null表示将保留关键字不变。split_queries_on_whitespace在构建针对此字段的查询时全文查询是否应在空格上拆分输入。接受true或false默认。time_series_dimension[预览]此功能处于技术预览状态可能会在将来的版本中更改或删除。Elastic将尽最大努力解决任何问题但技术预览中的功能不适用于正式发布功能的支持SLA。
常量关键字字段类型
常量关键字是用于索引中的所有文档都具有相同值的关键字字段的专用类型。它支持与关键字字段相同的查询和聚合但利用了所有文档在索引中都具有相同值的事实来更有效地执行查询。
您可以提交既不包含该字段值也不具有与映射中配置的值相同的值的文档。以下两个索引请求是等效的
POST logs-debug/_doc{date: 2019-12-12,message: Starting up Elasticsearch,level: debug
}POST logs-debug/_doc
{date: 2019-12-12,message: Starting up Elasticsearch
}然而提供与映射中配置的值不同的值是不允许的。如果映射中未提供值则字段将根据第一个索引的文档中包含的值自动配置自身。尽管此行为可能很方便但请注意这意味着如果有一个错误的值则单个有毒文档可能导致拒绝所有其他文档。
在提供值之前无论是通过映射还是从文档中字段上的查询将不匹配任何文档包括exists查询。一旦设置了该值字段的值将无法更改。
常量关键字字段的参数
常量关键字字段接受以下映射参数
meta有关字段的元数据。value要与索引中的所有文档关联的值。如果未提供此参数则将根据首个索引的文档设置值。
通配符字段类型
通配符字段类型是用于非结构化的机器生成内容的专用关键字字段您计划使用类似grep的通配符和正则表达式查询进行搜索。通配符类型经过优化适用于具有大值或高基数的字段。
如果您选择通配符字段类型您可以根据字段值的基数和大小将该字段映射为关键字或通配符字段。如果符合以下条件之一可以使用通配符类型
该字段包含超过一百万个唯一值。 AND您计划经常使用具有前导通配符的模式进行字段搜索例如foo或baz。该字段包含大于32KB的值。 AND您计划经常使用任何通配符模式搜索该字段。
否则使用关键字字段类型进行更快的搜索、更快的索引和更低的存储成本。如果以前使用文本字段索引非结构化的机器生成内容您可以重新索引以更新映射为关键字或通配符字段。此外我们建议您更新应用程序或工作流程以替换字段上的基于单词的全文查询为等效的术语级别查询。
通配符字段内部索引整个字段值使用ngrams并存储完整字符串。索引用作粗略过滤器用于减少检索和检查完整值的数量。此字段特别适用于在日志行上运行类似grep的查询。通常情况下存储成本低于关键字字段但在完全术语匹配上搜索速度较慢。如果字段值共享许多前缀例如同一网站的URL通配符字段的存储成本可能高于等效的关键字字段。
在通配符字段上执行索引和搜索的示例
PUT my-index-000001
{mappings: {properties: {my_wildcard: {type: wildcard}}}
}PUT my-index-000001/_doc/1
{my_wildcard : This string can be quite lengthy
}GET my-index-000001/_search
{query: {wildcard: {my_wildcard: {value: *quite*lengthy}}}
}通配符字段的参数
通配符字段接受以下参数
null_value接受字符串值用于替代任何显式的null值。默认为null这意味着将字段视为缺失。ignore_above不要索引任何长于此值的字符串。默认为2147483647以便接受所有值。限制通配符字段类似于关键字字段因此不支持依赖于单词位置的查询如短语查询。运行通配符查询时任何重写参数都将被忽略。评分始终是常数分数。
嵌套字段类型 Nested field type
嵌套字段类型是对象数据类型的专用版本允许数组中的对象以一种可以独立查询的方式进行索引。
当在索引中包含大型、具有大量任意键的键值对时您可以考虑将每个键值对建模为具有键和值字段的嵌套文档。然而可以考虑使用平铺数据类型它将整个对象映射为单个字段并允许对其内容进行简单搜索。嵌套文档和查询通常开销较大因此对于这种用例使用平铺数据类型是更好的选择。
如何展平对象数组
Elasticsearch没有内部对象的概念。因此它将对象层次结构展平为字段名称和值的简单字段列表。例如考虑以下文档
PUT my-index-000001/_doc/1
{group : fans,user : [ {first : John,last : Smith},{first : Alice,last : White}]
}user字段被动态添加为对象类型字段。前面的文档在内部将被转换为一个更像这样的文档
{group : fans,user.first : [ alice, john ],user.last : [ smith, white ]
}user.first和user.last字段被展平为多值字段并且丢失了alice和white之间的关联。这个文档将错误地匹配包含alice和smith的查询
GET my-index-000001/_search
{query: {bool: {must: [{ match: { user.first: Alice }},{ match: { user.last: Smith }}]}}
}使用嵌套字段处理对象数组
如果需要索引对象数组并保持数组中每个对象的独立性请使用嵌套数据类型而不是对象数据类型。
在内部嵌套对象将数组中的每个对象作为单独的隐藏文档进行索引这意味着可以使用嵌套查询独立查询每个嵌套对象
PUT my-index-000001
{mappings: {properties: {user: {type: nested }}}
}PUT my-index-000001/_doc/1
{group : fans,user : [{first : John,last : Smith},{first : Alice,last : White}]
}GET my-index-000001/_search
{query: {nested: {path: user,query: {bool: {must: [{ match: { user.first: Alice }},{ match: { user.last: Smith }} ]}}}}
}嵌套字段的参数
嵌套字段接受以下参数
dynamic可选字符串是否应动态添加新属性到现有的嵌套对象。接受true默认、false和strict。properties可选对象嵌套对象内部的字段可以是任何数据类型包括嵌套。可以向现有的嵌套对象添加新属性。include_in_parent可选布尔值如果为true则嵌套对象中的所有字段也会作为标准平铺字段添加到父文档中。默认为false。include_in_root可选布尔值如果为true则嵌套对象中的所有字段也会作为标准平铺字段添加到根文档中。默认为false。
嵌套映射和对象的限制
如前所述每个嵌套对象都作为单独的Lucene文档进行索引。继续以前的示例如果我们索引了包含100个用户对象的单个文档那么将创建101个Lucene文档一个用于父文档一个用于每个嵌套对象。由于嵌套映射开销较大Elasticsearch采取了措施来防止性能问题 index.mapping.nested_fields.limit索引中唯一嵌套映射的最大数量。嵌套类型应仅在特殊情况下使用当需要查询独立的对象数组时。为了防止不良设计的映射此设置限制了每个索引中唯一嵌套类型的数量。默认值为50。 index.mapping.nested_objects.limit单个文档中跨所有嵌套类型包含的最大嵌套JSON对象数。此限制有助于防止在文档包含太多嵌套对象时出现内存不足错误。默认值为10000。
例如如果在前面的示例映射中添加了另一个名为comments的嵌套类型那么每个文档的用户和评论对象的组合数量必须在限制之下。
数值字段类型 Numeric
Elasticsearch支持以下数值类型
long带符号的64位整数最小值为-263最大值为263-1。integer带符号的32位整数最小值为-231最大值为231-1。short带符号的16位整数最小值为-32,768最大值为32,767。byte带符号的8位整数最小值为-128最大值为127。double双精度64位IEEE 754浮点数限制为有限值。float单精度32位IEEE 754浮点数限制为有限值。half_float半精度16位IEEE 754浮点数限制为有限值。scaled_float由长整数支持的浮点数乘以一个固定的双精度缩放因子。unsigned_long无符号的64位整数最小值为0最大值为264-1。
以下是配置具有数值字段的映射的示例
PUT my-index-000001
{mappings: {properties: {number_of_bytes: {type: integer},time_in_seconds: {type: float},price: {type: scaled_float,scaling_factor: 100}}}
}double、float和half_float类型认为-0.0和0.0是不同的值。因此在-0.0上执行term查询不会匹配0.0反之亦然。同样对于范围查询也是如此如果上限是-0.0那么0.0不会匹配如果下限是0.0那么-0.0不会匹配。
应该使用哪种类型
对于整数类型byte、short、integer和long应选择足够满足用例的最小类型。这将有助于更高效地进行索引和搜索。但请注意存储是根据实际存储的值进行优化的因此选择一个类型而不是另一个不会影响存储要求。
对于浮点数类型通常更有效的方法是使用缩放因子将浮点数据存储为整数这正是scaled_float类型在底层执行的操作。例如价格字段可以存储在具有缩放因子100的scaled_float中。所有API都将按照字段存储为双精度浮点数进行操作但在底层Elasticsearch将使用以分为单位的数值即price*100这是一个整数。这在大多数情况下有助于节省磁盘空间因为整数比浮点数更容易压缩。scaled_float也可用于在精度和磁盘空间之间进行权衡。例如假设您正在跟踪CPU利用率其值在0到1之间。通常CPU利用率是12.7%或13%之间没有太大差异因此可以使用缩放因子为100的scaled_float以将CPU利用率四舍五入到最接近的百分比以节省空间。
如果scaled_float不合适那么在浮点数类型double、float和half_float中应选择满足用例的最小类型。以下是一个比较这些类型以帮助做出决策的表格
类型最小值最大值有效位数/位数double2-1074(2-2-52)·2102353 / 15.95float2-149(2-2-23)·212724 / 7.22half_float2-246550411 / 3.31
映射数值标识符
并非所有数值数据都应该映射为数值字段数据类型。Elasticsearch会优化数值字段例如整数或长整数以进行范围查询。但是关键字字段更适用于术语和其他术语级查询。
例如ISBN或产品ID等标识符很少用于范围查询。但通常会使用术语级查询来检索它们。
如果您不打算使用范围查询来搜索标识符数据同时需要快速检索则可以将数值标识符映射为关键字字段。关键字字段上的术语查询通常比数值字段上的术语查询更快。
如果您不确定使用哪种类型可以使用多字段来将数据同时映射为关键字和数值数据类型。
数值字段的参数
数值类型字段接受以下参数
boost映射字段级别的查询时间加权。接受浮点数默认值为1.0。coerce
尝试将字符串转换为数字并对整数截断小数部分。接受true默认和false。不适用于unsigned_long。请注意如果使用script参数则不能设置此参数。
doc_values字段是否以列分隔方式存储在磁盘上以便以后用于排序、聚合或脚本接受true默认或false。ignore_malformed如果为true则会忽略格式不正确的数字。如果为false默认则格式不正确的数字会引发异常并拒绝整个文档。请注意如果使用script参数则不能设置此参数。index字段是否可搜索接受true默认或false。meta关于字段的元数据。null_value接受与字段类型相同的数值值用于替代任何显式的null值。默认为null表示字段视为丢失。请注意如果使用script参数则不能设置此参数。on_script_error定义了在索引时由script参数定义的脚本引发错误时要执行的操作。接受fail默认将导致整个文档被拒绝和continue将在文档的_ignored元数据字段中注册字段并继续索引。只有在设置了script字段时才能设置此参数。script如果设置了此参数字段将索引由此脚本生成的值而不是直接从源中读取值。如果在输入文档中为此字段设置了值则将拒绝文档并显示错误。脚本的格式与其运行时等效项相同。只能在长整数和双精度字段类型上配置脚本。store字段值是否应与_source字段分开存储和检索接受true或false默认。time_series_dimension预览功能仅供Elastic内部使用。time_series_metric预览功能仅供Elastic内部使用。
scaled_float参数
scaled_float接受一个额外参数
scaling_factor在编码值时要使用的缩放因子。值将在索引时乘以此因子并四舍五入到最接近的长整数值。例如具有缩放因子10的scaled_float将在内部以23的形式存储2.34而所有搜索时操作查询、聚合、排序都将按照文档具有值2.3的方式运行。较高的缩放因子值会提高精度但也会增加空间要求。此参数是必需的。
对象字段类型 objecdt
JSON文档具有层次结构文档可能包含内部对象而这些内部对象本身也可以包含内部对象
PUT my-index-000001/_doc/1
{ region: US,manager: { age: 30,name: { first: John,last: Smith}}
}外部文档本身也是一个JSON对象。它包含一个名为manager的内部对象而manager内部又包含一个名为name的内部对象。
在内部此文档被索引为一组简单的键值对类似于以下结构
{region: US,manager.age: 30,manager.name.first: John,manager.name.last: Smith
}上述文档的显式映射可能如下所示
PUT my-index-000001
{mappings: {properties: { region: {type: keyword},manager: { properties: {age: { type: integer },name: { properties: {first: { type: text },last: { type: text }}}}}}}
}上述映射示例中
properties位于顶级映射定义中。manager字段是一个内部对象字段。manager.name字段是manager字段内部的内部对象字段。
您不必显式将字段类型设置为object因为这是默认值。
对象字段的参数
对象字段接受以下参数
dynamic是否应动态添加新属性到现有对象中。接受true默认、runtime、false和strict。enabled对象字段的JSON值是否应被解析和索引true默认或者完全忽略false。properties对象内的字段可以是任何数据类型包括对象。可以向现有对象添加新属性。
如果您需要索引对象数组而不是单个对象请首先阅读关于嵌套字段的部分。
Percolator字段类型
Percolator字段类型是Elasticsearch的一种字段类型它将JSON结构解析为本机查询并存储该查询以便于后续的Percolate查询可以使用它来匹配提供的文档。
任何包含JSON对象的字段都可以配置为Percolator字段。Percolator字段类型没有特定的设置。只需配置Percolator字段类型就足以告诉Elasticsearch将某个字段视为查询。
如果按照以下映射配置Percolator字段类型
PUT my-index-000001
{mappings: {properties: {query: {type: percolator},field: {type: text}}}
}然后您可以索引一个查询
PUT my-index-000001/_doc/match_value
{query: {match: {field: value}}
}在Percolator查询中引用的字段必须已经存在于与Percolation相关的索引的映射中。为了确保这些字段存在可以通过create index或update mapping API来添加或更新映射。
重新索引Percolator查询有时是必需的以便从新版本中改进的Percolator字段类型中受益。
可以使用reindex API来重新索引Percolator查询。让我们看看以下具有Percolator字段类型的索引
PUT index
{mappings: {properties: {query : {type : percolator},body : {type: text}}}
}POST _aliases
{actions: [{add: {index: index,alias: queries }}]
}PUT queries/_doc/1?refresh
{query : {match : {body : quick brown fox}}
}建议为索引定义一个别名这样在重新索引时系统/应用程序无需更改即可知道Percolator查询现在位于不同的索引中。
假设您要升级到新的主要版本并且为了让新的Elasticsearch版本仍能读取您的查询您需要将查询重新索引到当前Elasticsearch版本的新索引中
PUT new_index
{mappings: {properties: {query : {type : percolator},body : {type: text}}}
}POST /_reindex?refresh
{source: {index: index},dest: {index: new_index}
}POST _aliases
{actions: [ {remove: {index : index,alias: queries}},{add: {index: new_index,alias: queries}}]
}如果存在别名请不要忘记将其指向新的索引。
通过别名queries执行Percolate查询
GET /queries/_search
{query: {percolate : {field : query,document : {body : fox jumps over the lazy dog}}}
}现在匹配将从新索引中返回。
优化查询时间文本分析
当Percolator验证Percolator候选匹配时它将解析、执行查询时间文本分析并实际运行Percolator查询以匹配正在Percolating的文档。这将为每个候选匹配执行每次执行Percolate查询时都会发生。如果您的查询时间文本分析是查询解析的相对昂贵部分那么文本分析可能成为Percolating时花费时间的支配因素。当Percolator最终验证了许多Percolator查询匹配时这种查询解析开销可能变得明显。
为了避免在Percolate时间最昂贵的文本分析部分可以选择在索引Percolator查询时执行昂贵的文本分析部分。这需要使用两种不同的分析器。第一个分析器实际上执行需要执行的文本分析昂贵部分。第二个分析器通常是whitespace只是拆分第一个分析器生成的标记。然后在索引Percolator查询之前应使用分析API使用较昂贵的分析器来分析查询文本。分析API的结果即标记应替换Percolator查询中的原始查询文本。重要的是查询现在应该配置为覆盖映射中的分析器并仅使用第二个分析器。大多数基于文本的查询支持分析器选项如match、query_string、simple_query_string。使用这种方法昂贵的文本分析只会执行一次而不是多次。
让我们通过一个简化的示例演示这个工作流程。
假设我们要索引以下Percolator查询
{query : {match : {body : {query : missing bicycles}}}
}以及以下的设置和映射
PUT /test_index
{settings: {analysis: {analyzer: {my_analyzer : {tokenizer: standard,filter : [lowercase, porter_stem]}}},mappings: {properties: {query : {type: percolator},body : {type: text,analyzer: my_analyzer }}}}
}出于本示例的目的这个分析器被认为是昂贵的。
首先我们需要使用分析API在索引之前执行文本分析
POST /test_index/_analyze
{analyzer : my_analyzer,text : missing bicycles
}这将产生以下响应
{tokens: [{token: miss,start_offset: 0,end_offset: 7,type: ALPHANUM,position: 0},{token: bicycl,start_offset: 8,end_offset: 16,type: ALPHANUM,position: 1}]
}返回的标记按照生成的顺序需要替换Percolator查询中的查询文本
PUT /test_index/_doc/1?refresh
{query : {match : {body : {query : miss bicycl,analyzer : whitespace }}}
}重要的是选择whitespace分析器否则将使用映射中定义的分析器这将破坏使用这个工作流的目的。请注意whitespace是内置分析器如果需要使用不同的分析器必须首先在索引的设置中进行配置。
在Percolate时间什么都不会改变Percolate查询可以正常定义
GET /test_index/_search
{query: {percolate : {field : query,document : {body : Bycicles are missing}}}
}这将产生类似以下的响应
{took: 6,timed_out: false,_shards: {total: 1,successful: 1,skipped : 0,failed: 0},hits: {total : {value: 1,relation: eq},max_score: 0.13076457,hits: [{_index: test_index,_type: _doc,_id: 1,_score: 0.13076457,_source: {query: {match: {body: {query: miss bicycl,analyzer: whitespace}}}},fields : {_percolator_document_slot : [0]}}]}
}这个Percolate查询现在来自新索引。
优化通配符查询
通配符查询比其他查询更昂贵特别是如果通配符表达式很大的话。
对于具有前缀通配符表达式或仅前缀查询的通配符查询可以使用edge_ngram标记过滤器将这些查询替换为针对配置了edge_ngram标记过滤器的字段的常规词项查询。
创建具有自定义分析设置的索引
PUT my_queries1
{settings: {analysis: {analyzer: {wildcard_prefix: { type: custom,tokenizer: standard,filter : [lowercase,wildcard_edge_ngram]}},filter: {wildcard_edge_ngram: { type: edge_ngram,min_gram: 1,max_gram: 32}}}},mappings: {properties: {query : {type : percolator},my_field: {type: text,fields: {prefix: { type: text,analyzer: wildcard_prefix,search_analyzer: standard}}}}}
}分析器在索引时间只需要生成前缀标记。
根据前缀搜索需求增加min_gram并减小max_gram设置。
此多字段应用于使用term或match查询而不是prefix或通配符查询进行前缀搜索。
然后不是索引以下查询
{query: {wildcard: {my_field: abc*}
}应该索引以下查询
PUT /my_queries1/_doc/1?refresh
{query : {term: {my_field.prefix: abc}}
}这种方式可以更有效地处理第二个查询而不是第一个查询。
以下搜索请求将与先前索引的Percolator查询匹配
GET /my_queries1/_search
{query: {percolate: {field: query,document: {my_field: abcd}}}
}同样这是一种优化前缀通配符搜索的技术。通过使用reverse标记过滤器和edge_ngram标记过滤器来处理后缀通配符搜索可以采用相同的技术。这使得后缀通配符搜索更加高效。对于后缀通配符搜索需要在索引之前配置reverse标记过滤器。
PUT my_queries2
{settings: {analysis: {analyzer: {wildcard_suffix: {type: custom,tokenizer: standard,filter: [lowercase,reverse,wildcard_edge_ngram]},wildcard_suffix_search_time: {type: custom,tokenizer: standard,filter: [lowercase,reverse]}},filter: {wildcard_edge_ngram: {type: edge_ngram,min_gram: 1,max_gram: 32}}}},mappings: {properties: {query : {type : percolator},my_field: {type: text,fields: {suffix: {type: text,analyzer: wildcard_suffix,search_analyzer: wildcard_suffix_search_time }}}}}
}搜索时需要使用自定义分析器因为否则查询项不会被反转否则将不会与反转后缀标记匹配。
然后不是索引以下查询
{query: {wildcard: {my_field: *xyz}
}应该索引以下查询
PUT /my_queries2/_doc/2?refresh
{query: {match: { my_field.suffix: xyz}}
}应该使用match查询而不是term查询因为文本分析需要反转查询项。
以下搜索请求将与先前索引的Percolator查询匹配
GET /my_queries2/_search
{query: {percolate: {field: query,document: {my_field: wxyz}}}
}专用的Percolator索引
Percolate查询可以添加到任何索引中。与将Percolate查询添加到数据所在的索引不同这些查询也可以添加到专用索引中。这样做的好处是这个专用的Percolator索引可以有自己的索引设置例如主分片和副本分片的数量。如果选择使用专用的Percolate索引需要确保普通索引上的映射也可用于Percolate索引。否则Percolate查询可能会被错误解析。
强制将未映射的字段处理为字符串
在某些情况下不清楚要注册哪种Percolator查询如果没有字段映射的字段在Percolator查询中引用那么添加Percolator查询将失败。这意味着需要更新映射以具有具有适当设置的字段然后才能添加Percolator查询。但有时只需将所有未映射的字段处理为默认的文本字段就足够了。在这种情况下可以将index.percolator.map_unmapped_fields_as_text设置为true默认为false然后如果Percolator查询中引用的字段不存在它将被处理为默认的文本字段以便添加Percolator查询不会失败。
限制
父/子关系由于Percolate查询一次处理一个文档因此不支持针对子文档运行的查询和过滤器例如has_child和has_parent。
获取查询有一些查询通过查询解析期间的get调用来获取数据。例如当使用terms查找时模板查询使用索引脚本geo_shape在使用预先索引的形状时。当这些查询由Percolator字段类型索引时get调用将执行一次。因此每次Percolator查询评估这些查询时都将使用它们在索引时的获取的术语、形状等数据。需要注意的是这些查询的获取术语等操作发生在每次在主分片和副本分片上进行索引时因此实际索引的术语可能在不同的分片副本之间不同如果源索引在索引时发生更改。
脚本查询脚本查询中的脚本只能访问文档值字段。Percolator查询将提供的文档索引到内存中的索引中。这个内存中的索引不支持存储字段因此不会存储_source字段和其他存储字段。这是脚本查询中无法使用_source和其他存储字段的原因。
字段别名包含字段别名的Percolator查询可能不会始终按预期行为。特别是如果注册了一个包含字段别名的Percolator查询然后在映
射中更改字段别名的目标Percolator查询将无法找到它要查找的字段。
point数据类型
point数据类型用于索引和搜索二维平面坐标系中的任意x、y对。您可以使用shape Query来查询此类型的文档。
下面演示了指定点的四种方式
将点表示为对象
PUT my-index-000001
{mappings: {properties: {location: {type: point}}}
}PUT my-index-000001/_doc/1
{text: Point as an object,location: { x: 41.12,y: -71.34}
}将点表示为字符串
PUT my-index-000001/_doc/2
{text: Point as a string,location: 41.12,-71.34
}将点表示为数组
PUT my-index-000001/_doc/4
{text: Point as an array,location: [41.12, -71.34]
}将点表示为Well-Known Text (WKT) POINT原语
PUT my-index-000001/_doc/5
{text: Point as a WKT POINT primitive,location : POINT (41.12 -71.34)
}这些方式分别表示了点可以使用不同的数据结构来表示点坐标。
以对象方式表示使用 “x” 和 “y” 键。以字符串方式表示使用格式 “x,y”。以数组方式表示使用格式 [x, y]。以Well-Known Text (WKT) POINT原语方式表示使用格式 “POINT(x y)”。
索引器提供的坐标是单精度浮点数值因此字段保证与Java虚拟机提供的相同的精度通常为1E-38。
point字段的参数如下 ignore_malformed如果设置为true则会忽略格式错误的点。如果设置为false默认值格式错误的点会引发异常并拒绝整个文档。 ignore_z_value如果设置为true默认值将接受三维点存储在_source字段中但只会索引x和y值第三维度将被忽略。如果设置为false包含超过x和y二维值的点将引发异常并拒绝整个文档。 null_value接受一个点值用于替代任何显式的null值。默认为null这意味着该字段将被视为缺失。
排序和检索点
目前无法直接对点进行排序或检索其字段。点值仅通过_source字段检索。 range字段类型表示介于上限和下限之间的连续数值范围。例如一个范围可以表示十月份的任何日期或从0到9的任何整数。它们使用下限gt或gte和上限lt或lte运算符进行定义。可以用于查询并对聚合提供有限支持。唯一支持的聚合是直方图histogram和基数cardinality。
范围字段类型 range
支持以下range类型 integer_range带有最小值-231和最大值231-1的有符号32位整数的范围。 float_range带有单精度32位IEEE 754浮点数值的范围。 long_range带有最小值-263和最大值263-1的有符号64位整数的范围。 double_range带有双精度64位IEEE 754浮点数值的范围。 date_range日期值的范围。日期范围支持通过format映射参数的各种日期格式。无论使用哪种格式日期值都会被解析为自Unix纪元以来的UTC毫秒数的无符号64位整数。不支持包含now日期数学表达式的值。 ip_range支持IPv4或IPv6或混合地址的IP值范围。
以下是配置具有不同range字段的映射的示例以及索引多种range类型的示例
PUT range_index
{settings: {number_of_shards: 2},mappings: {properties: {expected_attendees: {type: integer_range},time_frame: {type: date_range, format: yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis}}}
}PUT range_index/_doc/1?refresh
{expected_attendees : { gte : 10,lt : 20},time_frame : {gte : 2015-10-31 12:00:00, lte : 2015-11-01}
}date_range类型接受由日期类型定义的相同字段参数。
示例中索引了一个具有10到20名与会者不包括20名的会议。
以下是对名为expected_attendees的integer_range字段的term查询示例。12是范围内的值因此会匹配。
GET range_index/_search
{query : {term : {expected_attendees : {value: 12}}}
}上述查询的结果。
{took: 13,timed_out: false,_shards : {total: 2,successful: 2,skipped : 0,failed: 0},hits : {total : {value: 1,relation: eq},max_score : 1.0,hits : [{_index : range_index,_type : _doc,_id : 1,_score : 1.0,_source : {expected_attendees : {gte : 10, lt : 20},time_frame : {gte : 2015-10-31 12:00:00, lte : 2015-11-01}}}]}
}下面是针对名为time_frame的date_range字段的date_range查询示例。
GET range_index/_search
{query : {range : {time_frame : { gte : 2015-10-31,lte : 2015-11-01,relation : within }}}
}range查询的工作方式与上面描述的range查询相同。
对range字段的range查询支持relation参数可以是WITHIN、CONTAINS、INTERSECTS默认值之一。
这个查询会产生类似的结果。
{took: 13,timed_out: false,_shards : {total: 2,successful: 2,skipped : 0,failed: 0},hits : {total : {value: 1,relation: eq},max_score : 1.0,hits : [{_index : range_index,_type : _doc,_id : 1,_score : 1.0,_source : {expected_attendees : {gte : 10, lt : 20},time_frame : {gte : 2015-10-31 12:00:00, lte : 2015-11-01}}}]}
}IP范围 除了上面的范围格式IP范围可以使用CIDR表示法 PUT range_index/_mapping { “properties”: { “ip_allowlist”: { “type”: “ip_range” } } }
PUT range_index/_doc/2 { “ip_allowlist” : “192.168.0.0/16” } range字段的参数如下 coerce尝试将字符串转换为数字并截断整数的小数部分。接受true默认值和false。 boost映射字段级别的查询时间加权。接受浮点数默认为1.0。 index字段是否可搜索接受true默认值和false。 store字段值是否应存储在_source字段之外以便检索接受true或false默认值。
特征排名字段类型 rank_feature
rank_feature字段类型用于索引数字以便在后续的查询中使用rank_feature查询来提升文档的相关性。
下面是一个示例首先创建一个名为my-index-000001的索引其中包含两个rank_feature字段然后向该索引中添加一个文档并执行一个rank_feature查询
PUT my-index-000001
{mappings: {properties: {pagerank: {type: rank_feature },url_length: {type: rank_feature,positive_score_impact: false }}}
}PUT my-index-000001/_doc/1
{pagerank: 8,url_length: 22
}GET my-index-000001/_search
{query: {rank_feature: {field: pagerank}}
}上述示例中首先创建了my-index-000001索引其中包含两个rank_feature字段pagerank和url_length。pagerank字段的默认行为是正相关而url_length字段设置为负相关。
然后向该索引中添加了一个文档该文档包含了这两个字段的值。
最后执行了一个rank_feature查询以使用pagerank字段来影响文档的相关性得分。
需要注意的是
rank_feature字段类型仅支持单值字段和严格正值。多值字段和负值将被拒绝。rank_feature字段不支持查询、排序或聚合。它们只能在rank_feature查询中使用。rank_feature字段只保留了9个有效位数的精度这对应着大约0.4%的相对误差。与得分负相关的rank_feature字段应将positive_score_impact设置为false默认为true。这将由rank_feature查询来使用以修改评分公式使得分随特征值的增加而减少。
排名特征字段类型 rank_features
rank_features字段是一种用于索引数值特征向量的字段以便在后续的查询中使用rank_feature查询来增强文档的排名。
它类似于rank_feature数据类型但更适用于特征列表稀疏的情况以便不必为每个特征添加一个字段到映射中。
以下是一个示例
PUT my-index-000001
{mappings: {properties: {topics: {type: rank_features },negative_reviews : {type: rank_features,positive_score_impact: false }}}
}PUT my-index-000001/_doc/1
{topics: { politics: 20,economics: 50.8},negative_reviews: {1star: 10,2star: 100}
}PUT my-index-000001/_doc/2
{topics: {politics: 5.2,sports: 80.1},negative_reviews: {1star: 1,2star: 10}
}上述示例中我们创建了一个名为my-index-000001的索引其中包含两个rank_features字段一个名为topics另一个名为negative_reviews。negative_reviews字段还设置了positive_score_impact为false表示与分数负相关的特征。
rank_features字段必须使用rank_features字段类型。它们只支持单值特征和严格正数值。多值字段和零值或负值将被拒绝。
rank_features字段不支持排序或聚合只能使用rank_feature查询进行查询。
rank_features字段只保留9个有效位数的精度这对应大约0.4%的相对误差。
与分数负相关的rank_features应将positive_score_impact设置为false默认为true。这将由rank_feature查询用于修改评分公式使得分数随着特征值的增加而降低而不是增加。
键入时搜索字段类型 search_as_you_type
search_as_you_type字段类型是一种文本字段经过优化提供了对满足as-you-type自动完成用例的查询的开箱即用支持。它创建一系列子字段这些子字段经过分析以索引可以有效匹配部分匹配整个索引文本值的查询的术语。支持前缀完成即匹配从输入的开始处开始的术语和中缀完成即匹配输入中的任何位置的术语。
当将此类型的字段添加到映射中时可以使用以下示例
PUT my-index-000001
{mappings: {properties: {my_field: {type: search_as_you_type}}}
}这将创建以下字段
my_field根据映射配置进行分析。如果没有配置分析器则使用索引的默认分析器。my_field._2gram使用大小为2的shingle令牌过滤器包装my_field的分析器。my_field._3gram使用大小为3的shingle令牌过滤器包装my_field的分析器。my_field._index_prefix使用边缘ngram令牌过滤器包装my_field._3gram的分析器。
shingle子字段的大小可以使用max_shingle_size映射参数进行配置默认为3此参数的有效值是2至4之间的整数值。将为每个shingle大小从2到max_shingle_size创建子字段。my_field._index_prefix子字段将始终使用具有max_shingle_size的shingle子字段的分析器来构建自己的分析器。
增加max_shingle_size将提高具有更多连续术语的查询的匹配性但会增加索引大小。默认的max_shingle_size通常足够了。
通常为服务搜索即输入时完成用例而查询的最有效方法是使用类型为bool_prefix的multi_match查询该查询针对根search_as_you_type字段及其shingle子字段。这可以匹配查询术语的任何顺序但如果文档包含shingle子字段中的顺序术语则会为其打分更高。
GET my-index-000001/_search
{query: {multi_match: {query: brown f,type: bool_prefix,fields: [my_field,my_field._2gram,my_field._3gram]}}
}要搜索严格按顺序匹配查询术语的文档或者使用短语查询的其他属性请使用根字段上的match_phrase_prefix查询。如果最后一个术语应该精确匹配而不是作为前缀匹配则还可以使用match_phrase查询。使用短语查询可能比使用match_bool_prefix查询效率较低。
GET my-index-000001/_search
{query: {match_phrase_prefix: {my_field: brown f}}
}search_as_you_type字段类型的特定参数包括
max_shingle_size可选整数要创建的最大shingle大小。有效值为2包括到4包括。默认为3。为文本字段配置的analyzer、index、index_options、norms、store、search_analyzer、search_quote_analyzer、similarity和term_vector参数等与文本字段的配置类似。这些参数配置了根字段的子字段的行为。
优化前缀查询
当对根字段或任何其子字段进行前缀查询时查询将被重写为对._index_prefix子字段的项查询。这比通常对文本字段进行的前缀查询更有效因为每个shingle的前缀长度都直接作为项在._index_prefix子字段中索引。
._index_prefix子字段的分析器稍微修改了shingle生成行为以便还索引了通常不会作为shingle产生的术语末尾的前缀。例如如果将值quick brown
fox索引到search_as_you_type字段并设置max_shingle_size为3则还将索引术语brown fox和fox的前缀到._index_prefix子字段尽管它们不会出现在._3gram子字段中。这允许完成字段输入中的所有术语。
形状 shape
shape数据类型用于索引和搜索任意x、y平面形状如矩形和多边形。它可用于索引和查询其坐标位于二维平面坐标系中的几何形状。
您可以使用shape查询来查询此类型的文档。
映射选项 与geo_shape字段类型一样shape字段映射将GeoJSON或Well-Known TextWKT几何对象映射到shape类型。要启用它用户必须明确将字段映射到shape类型。以下是shape字段映射的选项
orientation可选地定义如何解释多边形/多多边形的顶点顺序。此参数定义了两个坐标系规则之一右手或左手每种规则可以以三种不同的方式指定。1. 右手规则right、ccw、counterclockwise2. 左手规则left、cw、clockwise。默认方向逆时针符合OGC标准该标准规定外部环的顶点按逆时针顺序排列内部环洞的顶点按顺时针顺序排列。在geo_shape映射中设置此参数会明确设置geo_shape字段的坐标列表的顶点顺序但可以在每个单独的GeoJSON或WKT文档中进行覆盖。ignore_malformed如果为true则忽略格式错误的GeoJSON或WKT形状。如果为false默认格式错误的GeoJSON和WKT形状将引发异常并拒绝整个文档。ignore_z_value如果为true默认将接受三维点存储在源中但仅索引纬度和经度值将忽略第三维。如果为false包含除纬度和经度两个维度值之外的geopoints将引发异常并拒绝整个文档。coerce如果为true将自动关闭多边形中的未闭合线环。
索引方法 与geo_shape一样shape字段类型通过将几何形状分解为三角网格并将每个三角形索引为BKD树中的7维点来进行索引。索引器提供的坐标是单精度浮点值因此该字段保证与Java虚拟机提供的相同精度通常为1E-38。对于多边形/多多边形三角剖分器的性能主要取决于定义几何形状的顶点数量。
重要说明 包含关系查询 - 支持将关系定义为包含的shape查询适用于使用ElasticSearch 7.5.0或更高版本创建的索引。
示例 以下是将geometry字段映射为shape类型的映射定义示例
PUT /example
{mappings: {properties: {geometry: {type: shape}}}
}该映射将geometry字段映射为shape类型。索引器使用单精度浮点值表示顶点值因此准确性保证与Java虚拟机提供的float值大致相同通常为1E-38。
输入结构 几何形状可以使用GeoJSON或Well-Known TextWKT格式表示。以下表提供了GeoJSON和WKT到Elasticsearch类型的映射
Point - POINT - point单个x、y坐标。LineString - LINESTRING - linestring由两个或多个点给定的任意线。Polygon - POLYGON - polygon首尾点必须匹配的封闭多边形因此创建一个n边多边形需要n 1个顶点至少4个顶点。MultiPoint - MULTIPOINT - multipoint一组未连接但可能相关的点。MultiLineString - MULTILINESTRING - multilinestring一组单独的线串。MultiPolygon - MULTIPOLYGON - multipolygon一组单独的多边形。GeometryCollection - GEOMETRYCOLLECTION - geometrycollection类似于multi*多边形的形状集合但多种类型可以共存例如一个点和一个线串。N/A - BBOX - envelope由指
定左上角和右下角点表示的边界矩形。
对于所有类型内部类型和坐标字段都是必需的。
GeoJSON和WKT以及Elasticsearch中的正确坐标顺序是X、Y在坐标数组内。这与许多地理空间API例如geo_shape通常使用的俚语纬度、经度Y、X顺序不同。
以下是GeoJSON和WKT中点的示例
POST /example/_doc
{location: {type: point,coordinates: [-377.03653, 389.897676]}
}POST /example/_doc
{location: POINT (-377.03653 389.897676)
}以下是GeoJSON和WKT中的LineString示例
POST /example/_doc
{location: {type: linestring,coordinates: [[-377.03653, 389.897676], [-377.009051, 389.889939]]}
}POST /example/_doc
{location: LINESTRING (-377.03653 389.897676, -377.009051 389.889939)
}以下是GeoJSON和WKT中的Polygon示例
POST /example/_doc
{location: {type: polygon,coordinates: [[ [1000.0, -1001.0], [1001.0, -1001.0], [1001.0, -1000.0], [1000.0, -1000.0], [1000.0, -1001.0] ]]}
}POST /example/_doc
{location: POLYGON ((1000.0 -1001.0, 1001.0 -1001.0, 1001.0 -1000.0, 1000.0 -1000.0, 1000.0 -1001.0))
}请注意第一个数组表示多边形的外边界其他数组表示内部形状“洞”。以下是带有洞的多边形的GeoJSON示例
POST /example/_doc
{location: {type: polygon,coordinates: [[ [1000.0, -1001.0], [1001.0, -1001.0], [1001.0, -1000.0], [1000.0, -1000.0], [1000.0, -1001.0] ],[ [1000.2, -1001.2], [1000.8, -1001.2], [1000.8, -1001.8], [1000.2, -1001.8], [1000.2, -1001.2] ]]}
}POST /example/_doc
{location: POLYGON ((1000.0 1000.0, 1001.0 1000.0, 1001.0 1001.0, 1000.0 1001.0, 1000.0 1000.0), (1000.2 1000.2, 1000.8 1000.2, 1000.8 1000.8, 1000.2 1000.8, 1000.2 1000.2))
}重要说明WKT不强制顶点的特定顺序。GeoJSON要求外多边形必须是逆时针的内部形状必须是顺时针的这与Open Geospatial ConsortiumOGC的Simple Feature Access规范的顶点顺序一致。
默认情况下Elasticsearch期望顶点按逆时针右手规则顺序排列。如果数据按顺时针左手规则顺序提供用户可以在字段映射中或作为文档的参数中更改orientation参数。以下是在文档中覆盖orientation参数的示例
POST /example/_doc
{location: {type: polygon,orientation: clockwise,coordinates: [[[1000.0, 1000.0], [1000.0, 1001.0], [1001.0, 1001.0], [1001.0, 1000.0], [1000.0, 1000.0] ]]}
}MultiPoint、MultiLineString、MultiPolygon和Geometry Collection的示例也类似。
文本 Text
文本字段是一种用于索引全文本值的字段类型比如电子邮件的正文或产品的描述。这些字段会进行分析也就是在被索引之前会通过分析器将字符串转换为独立的词汇项列表。分析过程允许Elasticsearch在每个全文本字段中搜索单独的词汇项。文本字段不用于排序很少用于聚合尽管“significant text”聚合是一个显著的例外。
文本字段最适用于非结构化但可读的内容。如果您需要索引非结构化的机器生成内容请参见Mapping unstructured content。如果您需要索引结构化内容如电子邮件地址、主机名、状态代码或标签那么您更可能应该使用关键字字段。
以下是文本字段的映射示例
PUT my-index-000001
{mappings: {properties: {full_name: {type: text}}}
}有时有必要在同一个字段上既拥有全文本text又拥有关键字keyword版本一个用于全文本搜索另一个用于聚合和排序。这可以通过多字段multi-fields来实现。
文本字段接受以下参数
analyzer文本字段在索引时和搜索时应使用的分析器。默认为默认的索引分析器或标准分析器。boost映射字段级别的查询时间加权。接受浮点数默认为1.0。eager_global_ordinals是否在刷新时急切加载全局序数接受true或false默认。启用这个选项对那些经常用于显著的词项聚合的字段是一个好主意。fielddata字段是否可以使用内存中的fielddata进行排序、聚合或脚本处理接受true或false默认。fielddata_frequency_filter专家设置允许决定在启用fielddata时要加载哪些值到内存中。默认情况下所有值都会被加载。fields多字段允许相同的字符串值以不同方式进行多次索引以满足不同的目的比如一个字段用于搜索一个多字段用于排序和聚合或者使用不同的分析器分析相同的字符串值。index字段是否可以被搜索接受true默认或false。index_options为了搜索和高亮显示的目的索引中应存储什么信息。默认为positions。index_prefixes如果启用将长度在2到5个字符之间的词项前缀索引到一个单独的字段中。这允许前缀搜索更高效但会增加索引的大小。index_phrases如果启用将两个词项的词组shingles索引到一个单独的字段中。这允许精确短语查询无偏移更高效但会增加索引的大小。norms是否在评分查询中考虑字段长度接受true默认或false。position_increment_gap应在字符串数组的每个元素之间插入的虚假词位置数。默认值为分析器上配置的position_increment_gap默认为100。100是之所以选择的数字是因为它可以防止有相当大偏移小于100的短语查询匹配跨字段值的词项。store字段值是否应存储并能够单独从_source字段中检索。接受true或false默认。search_analyzer搜索时应使用的分析器。默认为分析器设置。search_quote_analyzer遇到短语时在搜索时应使用的分析器。默认为search_analyzer设置。similarity应使用的评分算法或相似性。默认为BM25。term_vector是否应为字段存储词项向量。默认为no。meta关于字段的元数据。
文本字段通常默认是可搜索的但默认情况下不可用于聚合、排序或脚本。如果您尝试在文本字段上进行排序、聚合或从脚本中访问值将看到如下异常信息
“默认情况下文本字段上已禁用fielddata。请在your_field_name上设置fielddatatrue以通过反向索引加载fielddata到内存中。需要注意的是fielddata会使用大量内存。”
要在文本字段上启用fielddata您可以使用更新映射API如下所示
PUT my-index-000001/_mapping
{properties: {my_field: {type: text,fielddata: true}}
}fielddata_frequency_filter映射参数可以用于减少加载到内存中的词项数量从而降低内存使用。词项可以根据频率进行过滤。可以指定最小值和最大值以表示绝对数值当数值大于1.0时或百分比例如0.01表示1%而1.0表示100%。频率是根据段segment计算的。百分比是基于具有字段值的文档数来计算的而不是段中的所有文档数。
对小段segment可以使用min_segment_size完全排除方法是指定段应包含的最小文档数。
fielddata通常不适用于文本字段。fielddata存储在堆中因为它的计算成本很高。计算fielddata可能会导致延迟峰值并且增加堆使用是集群性能问题的原因之一。
大多数希望在文本字段上执行更多操作的用户使用多字段映射方法是同时拥有用于全文本搜索的文本字段和用于聚合的未分析的关键字字段如下所示
PUT my-index-000001
{mappings: {properties: {my_field: {type: text,fields: {keyword: {type: keyword}}}}}
}使用my_field字段进行搜索。使用my_field.keyword字段进行聚合、排序或在脚本中使用。
要在文本字段上启用fielddata您可以使用更新映射API如下所示
PUT my-index-000001/_mapping
{properties: {my_field: {type: text,fielddata: true}}
}match_only_text是文本的变体它在消耗空间效率时交换了位置查询的评分和效率。这个字段有效地以只索引文档index_options: docs的方式存储数据并禁用了标准化norms: false。术语查询的执行速度可能比文本字段更快不过需要查看_source文档来验证短语是否匹配因此需要查看位置的查询如match_phrase查询执行较慢。所有查询返回的分数恒定都等于1.0。
分析不可配置match_only_text始终使用默认分析器默认为标准分析器进行分析。
不支持span查询如果绝对需要span查询可以使用interval查询或text字段类型。
除此之外match_only_text支持与text相同的查询。与text一样它不支持排序并且只支持有限的聚合。
以下是match_only_text字段类型的映射示例
PUT logs
{mappings: {properties: {timestamp: {type: date},message: {type: match_only_text}}}
}match_only_text字段类型支持以下映射参数
fields多字段允许相同的字符串值以不同方式多次索引以满足不同目的例如一个字段用于搜索多字段用于排序和聚合或者使用不同的分析器分析相同的字符串值。meta关于字段的元数据。
Token count字段类型
Token count字段类型实际上是一个整数字段它接受字符串值对其进行分析然后索引字符串中的标记数。
例如
PUT my-index-000001
{mappings: {properties: {name: { type: text,fields: {length: { type: token_count,analyzer: standard}}}}}
}PUT my-index-000001/_doc/1
{ name: John Smith }PUT my-index-000001/_doc/2
{ name: Rachel Alice Williams }GET my-index-000001/_search
{query: {term: {name.length: 3 }}
}在这个示例中name字段是一个text字段它使用默认的标准分析器。
name.length字段是一个token_count多字段它将索引name字段中的标记数量。
这个查询只匹配包含Rachel Alice Williams的文档因为它包含三个标记。
token_count字段的参数包括
analyzer用于分析字符串值的分析器。enable_position_increments指示是否应计算位置增量。boost字段级别的查询时间加权。doc_values指示字段是否应以列存储方式存储在磁盘上。index指示字段是否可搜索。null_value用于替代任何显式空值的数值。store指示字段值是否应分开存储和可检索。
这个字段类型通常用于索引和查询文本中标记的数量而不是文本内容本身。
无符号长整数 Unsigned long
Unsigned long是一种数值字段类型表示无符号64位整数其最小值为0最大值为264-1从0到18446744073709551615包括边界值。
以下是一个示例
PUT my_index
{mappings: {properties: {my_counter: {type: unsigned_long}}}
}Unsigned long可以以数值或字符串形式进行索引表示范围在[0, 18446744073709551615]的整数值。它们不能具有小数部分。
以下是一个示例
POST /my_index/_bulk?refresh
{index:{_id:1}}
{my_counter: 0}
{index:{_id:2}}
{my_counter: 9223372036854775808}
{index:{_id:3}}
{my_counter: 18446744073709551614}
{index:{_id:4}}
{my_counter: 18446744073709551615}Term查询接受数值或字符串形式的任何数字。
以下是一个示例
GET /my_index/_search
{query: {term : {my_counter : 18446744073709551615}}
}范围查询的条件可以包含带有小数部分的值。在这种情况下Elasticsearch将其转换为整数值gte和gt条件被转换为最接近的整数上限包括在内而lt和lte范围被转换为最接近的整数下限包括在内。建议将范围作为字符串传递以确保它们被解析而没有丢失精度。
以下是一个示例
GET /my_index/_search
{query: {range : {my_counter : {gte : 9223372036854775808.5,lte : 18446744073709551615}}}
}对于具有sort的unsigned_long字段的查询对于特定文档如果该文档的值在long值范围内则Elasticsearch返回long类型的排序值如果值超出此范围则返回BigInteger类型的排序值。REST客户端需要能够处理JSON中的大整数值以正确支持此字段类型。
以下是一个示例
GET /my_index/_search
{query: {match_all : {}},sort : {my_counter : desc}
}目前在脚本中不支持unsigned_long。
对于unsigned_long的存储字段以字符串形式存储和返回。
对于terms聚合与排序值类似将使用Long或BigInteger值。对于其他聚合将值转换为double类型。
支持具有混合数值类型的搜索其中之一是unsigned_long除了排序查询。因此在两个索引上执行排序查询其中一个索引中具有unsigned_long类型的字段另一个索引中具有long类型的字段不会产生正确的结果应避免使用。如果需要此类排序可以改用基于脚本的排序。
支持具有多个数值类型的聚合其中之一是unsigned_long。在这种情况下将值转换为double类型。
版本字段类型 Version
版本字段类型是关键字字段的一个特例用于处理软件版本值并支持它们的专用优先规则。优先规则遵循语义化版本控制规则的规定例如主要、次要和修补版本部分按数字顺序排序即2.1.0 “2.4.1” “2.11.2”并且预发行版本在正式发布版本之前排序即1.0.0-alpha “1.0.0”。
您可以将版本字段索引如下
PUT my-index-000001
{mappings: {properties: {my_version: {type: version}}}
}该字段提供了与常规关键字字段相同的搜索功能。例如可以使用match或term查询进行精确匹配并支持前缀和通配符搜索。主要优点是范围查询将遵循Semver排序规则因此在1.0.0和1.5.0之间的范围查询将包括1.2.3版本但不包括1.11.2版本例如。请注意如果使用常规关键字字段进行索引那么排序是按字母顺序排列结果会不同。
软件版本应遵循语义化版本控制规则模式和优先规则有一个明显的例外即允许有三个或三个以上的主要版本标识符即1.2或1.2.3.4都被视为有效版本而在严格的Semver规则下它们不合格。不符合Semver定义的版本字符串例如1.2.alpha.4仍然可以进行索引和检索以进行精确匹配但它们将按照字母顺序排序后出现在任何具有有效版本的版本之后。空字符串被视为无效并在所有有效版本之后但在其他无效版本之前排序。
版本字段的参数包括
meta字段的元数据。
限制
该字段类型不针对重度使用通配符、正则表达式或模糊搜索进行了优化。虽然这些类型的查询在此字段中可行但如果您严重依赖于这些查询应考虑使用常规关键字字段。
元数据字段 Metadata fields
元数据字段是与每个文档相关的信息例如 _index索引、_type映射类型和 _id文档标识等。在创建映射类型时有些元数据字段的行为可以进行自定义。
身份元数据字段
_index索引文档所属的索引。_type映射类型文档的映射类型。_id文档标识文档的唯一标识符。
文档源元数据字段
_source_源包含文档主体的原始 JSON 数据。_size_大小由 mapper-size 插件提供的 _source 字段的大小以字节为单位。
文档计数元数据字段
_doc_count_文档计数用于存储文档代表的预聚合数据的自定义字段。
索引元数据字段
_field_names_字段名称文档中包含非空值的所有字段。_ignored_已忽略由于 ignore_malformed 而在索引时被忽略的文档中的所有字段。
路由元数据字段
_routing_路由自定义路由值用于将文档路由到特定的分片。
其他元数据字段
_meta_元数据应用程序特定的元数据。_tier_层级文档所属索引的当前数据层级首选项。
_doc_count field 文档计数字段 _bucket aggregations桶聚合总是返回一个名为 doc_count 的字段显示了每个桶中聚合和分区的文档数量。计算 doc_count 的值非常简单对于每个收集到的文档doc_count 会递增 1。
虽然这种简单的方法在计算针对单个文档的聚合时有效但它无法准确表示存储了预聚合数据例如直方图或 aggregate_metric_double 字段的文档因为一个汇总字段可能代表多个文档。
为了正确计算处理预聚合数据时的文档数量我们引入了一个名为 _doc_count 的元数据字段类型。_doc_count 必须始终是表示单个汇总字段中聚合的文档数量的正整数。
当将 _doc_count 字段添加到文档中时所有桶聚合将尊重其值并将桶的 doc_count 递增字段的值。如果文档不包含任何 _doc_count 字段默认情况下 _doc_count 1。
一个 _doc_count 字段只能在一个文档中存储一个正整数。不允许嵌套数组。
如果文档不包含 _doc_count 字段聚合器将递增 1这是默认行为。
示例
以下的创建索引 API 请求创建了一个具有以下字段映射的新索引
my_histogram用于存储百分位数数据的直方图字段 my_text用于存储直方图标题的关键字字段
PUT my_index
{mappings : {properties : {my_histogram : {type : histogram},my_text : {type : keyword}}
}以下的索引 API 请求存储了两个直方图的预聚合数据histogram_1 和 histogram_2。
PUT my_index/_doc/1
{my_text : histogram_1,my_histogram : {values : [0.1, 0.2, 0.3, 0.4, 0.5],counts : [3, 7, 23, 12, 6]},_doc_count: 45
}PUT my_index/_doc/2
{my_text : histogram_2,my_histogram : {values : [0.1, 0.25, 0.35, 0.4, 0.45, 0.5],counts : [8, 17, 8, 7, 6, 2]},_doc_count: 62
}_doc_count 字段必须是存储用于生成每个直方图的文档数量的正整数。
如果我们在 my_index 上运行以下的 terms 聚合
GET /_search
{aggs : {histogram_titles : {terms : { field : my_text }}}
}我们将得到以下响应
{...aggregations : {histogram_titles : {doc_count_error_upper_bound: 0,sum_other_doc_count: 0,buckets : [{key : histogram_2,doc_count : 62},{key : histogram_1,doc_count : 45}]}}
}这个响应显示了每个直方图标题的文档数量正确地反映了存储了 _doc_count 字段的文档的预聚合数据。 _field_names 字段名称 _field_names 字段用于索引包含任何非空值的字段的名称这些字段包含在文档中。此字段曾用于 exists 查询以查找具有或不具有特定字段的非空值的文档。
现在_field_names 字段仅索引已禁用 doc_values 和 norms 的字段的名称。对于启用了 doc_values 或 norm 的字段exists 查询仍然可用但不会使用 _field_names 字段。
禁用 _field_names 禁用 _field_names 已被弃用并将在未来的主要版本中移除。
通常情况下禁用 _field_names 不是必要的因为它不再像以前那样带有索引开销。如果您有许多已禁用 doc_values 和 norms 的字段且不需要使用这些字段执行 exists 查询您可以通过将以下内容添加到映射中来禁用 _field_names
PUT tweets
{mappings: {_field_names: {enabled: false}}
}这将禁用 _field_names 字段。 _ignored 字段 _ignored 字段用于索引和存储文档中在索引文档时被忽略的每个字段的名称。这可以出现在字段格式不正确且已启用 ignore_malformed 时或者当关键字字段的值超出其可选的 ignore_above 设置时。
此字段可通过 term、terms 和 exists 查询进行搜索并作为搜索命中的一部分返回。
例如以下查询将匹配所有包含一个或多个被忽略字段的文档
GET _search
{query: {exists: {field: _ignored}
}类似地以下查询将查找所有在索引时被忽略的文档的 timestamp 字段
GET _search
{query: {term: {_ignored: timestamp}
}这将找到所有在索引时被忽略的 timestamp 字段的文档。 _id field 每个文档都有一个唯一标识符 _id用于唯一标识文档并且已被索引以便可以使用 GET API 或 ids 查询来查找文档。_id 可以在索引时分配或者可以由Elasticsearch生成一个唯一的 _id。此字段在映射中不可配置。
_id 字段的值可以在诸如 term、terms、match 和 query_string 之类的查询中访问。
示例文档
PUT my-index-000001/_doc/1
{text: 带有 ID 1 的文档
}PUT my-index-000001/_doc/2?refreshtrue
{text: 带有 ID 2 的文档
}GET my-index-000001/_search
{query: {terms: {_id: [ 1, 2 ] }}
}通过 _id 字段进行查询也可参见 ids 查询
_id 字段受限于不可用于聚合、排序和脚本的限制。如果需要在 _id 字段上进行排序或聚合建议将 _id 字段的内容复制到启用了 doc_values 的另一个字段中。
_id 字段的大小限制为 512 字节更大的值将被拒绝。 _index field 在跨多个索引执行查询时有时希望添加与特定索引的文档相关的查询子句。_index 字段允许匹配文档被索引的索引。其值可以在某些查询和聚合以及在排序或脚本中访问
PUT index_1/_doc/1
{text: 在索引 1 中的文档
}PUT index_2/_doc/2?refreshtrue
{text: 在索引 2 中的文档
}GET index_1,index_2/_search
{query: {terms: {_index: [index_1, index_2] }},aggs: {indices: {terms: {field: _index, size: 10}}},sort: [{_index: { order: asc}}],script_fields: {index_name: {script: {lang: painless,source: doc[_index] }}}
}使用 _index 字段进行查询
在 _index 字段上进行聚合
在 _index 字段上进行排序
在脚本中访问 _index 字段
_index 字段在虚拟上是可用的它不会被添加到 Lucene 索引作为实际字段。这意味着您可以在术语或术语查询中使用 _index 字段或任何重写为术语查询的查询如 match、query_string 或 simple_query_string 查询以及前缀和通配符查询。但是它不支持正则表达式和模糊查询。
对 _index 字段的查询除了具体索引名称外还可以接受索引别名。
在指定远程索引名称时如 cluster_1:index_3查询必须包含分隔字符 :。例如对 cluster_:index_3 的通配符查询将匹配来自远程索引的文档。然而对 clusterindex_1 的查询仅匹配本地索引因为没有分隔符。此行为与远程索引名称的通常解析规则相一致。
_meta field 映射类型可以关联自定义元数据。Elasticsearch 并不直接使用这些元数据但可以用来存储特定于应用程序的元数据例如文档所属的类别
PUT my-index-000001
{mappings: {_meta: { class: MyApp::User,version: {min: 1.0,max: 1.3}}}
}可以使用 GET mapping API 检索此 _meta 信息。
可以使用 update mapping API 在现有类型上更新 _meta 字段
PUT my-index-000001/_mapping
{_meta: {class: MyApp2::User3,version: {min: 1.3,max: 1.5}}
}这使您可以随时更新映射类型的 _meta 元数据。这对于存储关于文档的附加信息或自定义应用程序数据非常有用。
_routing field
文档通过以下公式被路由到索引中的特定分片
routing_factor num_routing_shards / num_primary_shards shard_num (hash(_routing) % num_routing_shards) / routing_factor 其中num_routing_shards 是索引设置 index.number_of_routing_shards 的值num_primary_shards 是索引设置 index.number_of_shards 的值。
默认情况下_routing 的值是文档的 _id。可以通过为每个文档指定自定义的 _routing 值来实现自定义路由模式。例如
PUT my-index-000001/_doc/1?routinguser1refreshtrue
{title: 这是一个文档
}此文档使用 user1 作为其 _routing 值而不是其 ID。
在获取、删除或更新文档时需要提供相同的 _routing 值。
可以在查询中访问 _routing 字段的值
GET my-index-000001/_search
{query: {terms: {_routing: [ user1 ] }}
}使用 _routing 字段进行查询
数据流不支持自定义路由。取而代之的是将查询发送到数据流的适当后备索引。
使用自定义路由进行搜索
自定义路由可以降低搜索的影响。与其将搜索请求广播到索引中的所有分片不如将请求发送到与特定路由值或值匹配的分片
GET my-index-000001/_search?routinguser1,user2
{query: {match: {title: document}}
}此搜索请求仅在与 user1 和 user2 路由值关联的分片上执行。
使路由值为必需项
在使用自定义路由时重要的是在索引、获取、删除或更新文档时提供路由值。忘记路由值可能导致文档被索引到多个分片上。作为一种保障措施可以配置 _routing 字段使自定义路由值对所有 CRUD 操作都是必需的
PUT my-index-000002
{mappings: {_routing: {required: true }}
}在此示例中对于所有文档都要求路由。
唯一的 ID 与自定义路由
当索引文档时指定自定义 _routing 时不能保证 _id 在索引中的所有分片上是唯一的。实际上如果使用不同的 _routing 值索引具有相同 _id 的文档可能会出现在不同的分片上。
由用户负责确保 _id 在索引中是唯一的。
路由到索引分区
可以配置索引以使自定义路由值进入分片的子集而不是单个分片。这有助于减轻出现不平衡集群的风险同时仍然减小了搜索的影响。
要启用此功能需要在索引创建时提供 index.routing_partition_size 的索引级设置。随着分区大小的增加数据将更均匀地分布但每个请求将不得不搜索更多的分片。
启用此设置后计算分片的公式如下
routing_value hash(_routing) hash(_id) % routing_partition_size shard_num (routing_value % num_routing_shards) / routing_factor 即_routing 字段用于计算索引中的一组分片然后使用 _id 来选择该组内的分片。
为启用此功能index.routing_partition_size 的值应大于 1 且小于 index.number_of_shards。
一旦启用分区索引将具有以下限制
不能在其中创建具有关联字段关系的映射。 索引内的所有映射必须将 _routing 字段标记为必需的。
_source field _source 字段包含在索引时传递的原始 JSON 文档正文。_source 字段本身不被索引因此不可搜索但它被存储以便在执行获取或搜索等提取请求时可以返回。
禁用 _source 字段 虽然_source字段非常有用但它在索引中会产生存储开销。因此可以通过以下方式禁用它
PUT my-index-000001
{mappings: {_source: {enabled: false}}
}在禁用 _source 字段之前请考虑一下后果。如果_source字段不可用将不支持许多功能包括
update、update_by_query 和 reindex API。即时高亮显示。从一个 Elasticsearch 索引重新索引到另一个索引的能力无论是更改映射或分析还是将索引升级到新的主要版本。通过查看索引时使用的原始文档来调试查询或聚合的能力。可能在未来自动修复索引损坏的能力。
如果担心磁盘空间可以增加压缩级别而不是禁用 _source。
包括/排除字段从 _source 中 一个专家级的功能是在文档被索引后、但在 _source 字段存储之前可以修剪 _source 字段的内容。
从 _source 中删除字段与禁用 _source 具有类似的缺点特别是不能将文档从一个 Elasticsearch 索引重新索引到另一个索引。考虑使用源字段过滤而不是删除字段。
可以使用 includes/excludes 参数还接受通配符来进行如下设置
PUT logs
{mappings: {_source: {includes: [*.count,meta.*],excludes: [meta.description,meta.other.*]}}
}这些字段将从存储的 _source 字段中删除。
即使这些字段不在存储的 _source 中我们仍然可以在该字段上进行搜索。 _tier field
在跨多个索引执行查询时有时希望定位存储在给定数据层节点上的索引data_hot、data_warm、data_cold 或 data_frozen。_tier 字段允许匹配文档被索引到的索引的 tier_preference 设置。首选值可以在某些查询中访问
PUT index_1/_doc/1
{text: 在索引 1 中的文档
}PUT index_2/_doc/2?refreshtrue
{text: 在索引 2 中的文档
}GET index_1,index_2/_search
{query: {terms: {_tier: [data_hot, data_warm] }}
}使用 _tier 字段进行查询
通常查询将使用 terms 查询列出感兴趣的层级但您可以在任何被重写为术语查询的查询中使用 _tier 字段如 match、query_string、term、terms 或 simple_query_string 查询以及前缀和通配符查询。然而它不支持正则表达式和模糊查询。
索引的 tier_preference 设置是首选层级的逗号分隔列表按照首选层级主机索引的顺序排列首选层级在列表中首先列出然后是可能的多个备选选项。查询匹配只考虑首选项列表的第一个值。 映射参数 Mapping parameters Mapping parameters | Elasticsearch Guide [7.17] | Elastic 以下是常用的一些映射参数 analyzer: 用于指定分析器用于文本字段的文本分析。 boost: 用于调整字段的相关性得分可以提高或降低字段的权重。 doc_values: 指示是否在字段上启用 doc_values以便进行聚合和排序。 dynamic: 控制字段是否动态映射允许 Elasticsearch 自动检测字段类型。 enabled: 控制字段是否被启用或禁用可以用于临时禁用字段而不需要删除映射。 index: 控制字段是否被索引可以设置为 true、false 或 null使用默认设置。 store: 控制字段是否被存储以便在检索文档时获取原始值。 norms: 控制字段的归一化设置用于评分计算。 properties: 用于定义对象字段的子字段。 search_analyzer: 用于指定搜索时使用的分析器不同于索引时的分析器。 similarity: 用于指定字段的相似性设置影响相关性得分。
映射限制 以下是用于限制字段映射数量以防止映射爆炸的设置 index.mapping.total_fields.limit这是索引中字段的最大数量。字段和对象映射以及字段别名都计入这一限制。默认值为1000。此限制旨在防止映射和搜索变得过大。较高的值可能导致性能下降和内存问题尤其是在负载较高或资源较少的集群中。如果您增加此设置建议同时增加indices.query.bool.max_clause_count设置该设置限制了查询中的布尔子句的最大数量。 index.mapping.depth.limit这是字段的最大深度以内部对象数量来衡量。例如如果所有字段都在根对象级别定义那么深度为1。如果存在一个对象映射则深度为2依此类推。默认值为20。 index.mapping.nested_fields.limit这是索引中不同嵌套映射的最大数量。嵌套类型应仅在特殊情况下使用当需要独立查询对象数组时。为防止不良设计的映射此设置限制了每个索引中唯一嵌套类型的数量。默认值为50。 index.mapping.nested_objects.limit这是单个文档中包含的所有嵌套 JSON 对象的最大数量跨所有嵌套类型。此限制有助于防止文档包含过多嵌套对象时发生内存不足错误。默认值为10000。 index.mapping.field_name_length.limit此设置用于限制字段名称的最大长度。通常情况下不需要设置此设置因为默认设置是足够的除非用户开始添加具有非常长名称的大量字段。默认值是Long.MAX_VALUE没有限制。 index.mapping.dimension_fields.limit技术预览此功能处于技术预览阶段可能在将来的版本中更改或删除。它是 Elastic 内部使用的设置。
删除映射类型 从Elasticsearch 7.0.0开始不再支持默认映射类型_default_ mapping type。在6.x中创建的索引将在Elasticsearch 6.x中继续像以前一样运行。在7.0版本的API中映射类型被弃用并在索引创建、映射添加、映射获取、模板添加、模板获取以及字段映射获取等API中进行了破坏性更改。
什么是映射类型
自Elasticsearch首次发布以来每个文档都存储在单个索引中并分配给一个映射类型mapping type。映射类型用于表示要索引的文档或实体的类型例如Twitter索引可能包括用户类型user type和推文类型tweet type。
每个映射类型可以拥有自己的字段。例如用户类型可能包括full_name字段、user_name字段和email字段而推文类型可以包括content字段、tweeted_at字段和与用户类型相同的user_name字段。
每个文档都有一个名为_type的元数据字段其中包含类型名称。通过在URL中指定类型名称可以限制搜索仅在一个或多个类型中进行
GET twitter/user,tweet/_search
{query: {match: {user_name: kimchy}}
}_type字段与文档的_id组合生成_uid字段因此具有相同_id但不同类型的文档可以存在于单个索引中。
映射类型还用于建立文档之间的父子关系因此问题类型question的文档可以是答案类型answer的父文档。
为什么要移除映射类型
最初我们提到“索引”类似于SQL数据库中的“数据库”而“类型”等同于“表”。
这是一个不准确的类比它导致了错误的假设。在SQL数据库中各个表是相互独立的。一个表中的列与另一个表中具有相同名称的列之间没有关联。但在映射类型中的字段却不同。
在Elasticsearch索引中具有相同名称的字段在内部由相同的Lucene字段支持。换句话说在上面的示例中用户类型中的user_name字段与推文类型中的user_name字段实际上存储在相同的字段中并且两个user_name字段必须在两个类型中具有相同的映射定义。
这可能会导致困扰例如当您希望在同一索引中的一个类型中将deleted字段设为日期字段而在另一个类型中将其设为布尔字段时。
此外将不具备共同字段或仅有少数共同字段的不同实体存储在同一个索引中会导致数据稀疏干扰Lucene有效压缩文档的能力。
出于这些原因我们决定从Elasticsearch中移除映射类型的概念。
映射类型的替代方案 按文档类型创建索引Index per document type 第一种替代方案是为每个文档类型创建一个单独的索引。而不是将推文和用户存储在单个twitter索引中您可以在tweets索引中存储推文在users索引中存储用户。这些索引是完全独立的因此不会在不同索引之间发生字段类型冲突。此方法有两个好处数据更有可能是密集的因此可以受益于Lucene中使用的压缩技术全文搜索中用于评分的术语统计更可能准确因为同一索引中的所有文档代表单个实体。每个索引可以根据其包含的文档数量适当设置主分片的数量。 自定义类型字段Custom type field 当然每个群集中的主分片数量存在限制因此您可能不希望为只包含少数几千个文档的集合浪费整个主分片。在这种情况下您可以实现自定义类型字段它将类似于旧的_type。例如上面的用户/推文示例原本的工作流如下 PUT twitter
{mappings: {user: {properties: {name: { type: text },user_name: { type: keyword },email: { type: keyword }}},tweet: {properties: {content: { type: text },user_name: { type: keyword },tweeted_at: { type: date }}}}
}PUT twitter/user/kimchy
{name: Shay Banon,user_name: kimchy,email: shaykimchy.com
}PUT twitter/tweet/1
{user_name: kimchy,tweeted_at: 2017-10-24T09:00:00Z,content: Types are going away
}GET twitter/tweet/_search
{query: {match: {user_name: kimchy}}
}您可以通过添加自定义类型字段来实现相同的目标如下所示 PUT twitter
{mappings: {_doc: {properties: {type: { type: keyword
}, “name”: { “type”: “text” }, “user_name”: { “type”: “keyword” }, “email”: { “type”: “keyword” }, “content”: { “type”: “text” }, “tweeted_at”: { “type”: “date” } } } } }
PUT twitter/_doc/user-kimchy
{type: user, name: Shay Banon,user_name: kimchy,email: shaykimchy.com
}PUT twitter/_doc/tweet-1
{type: tweet, user_name: kimchy,tweeted_at: 2017-10-24T09:00:00Z,content: Types are going away
}GET twitter/_search
{query: {bool: {must: {match: {user_name: kimchy}},filter: {match: {type: tweet }}}}
}
显式的类型字段取代了隐式的_type字段。无映射类型的父子关系Parent/Child without mapping types 以前父子关系是通过将一个映射类型指定为父类型将一个或多个其他映射类型指定为子类型来表示的。没有映射类型我们不能再使用这种语法。父子关系特性将继续像以前一样运行只是表示文档之间关系的方式已更改为使用新的join字段。
映射类型移除的时间表
Elasticsearch 5.6.0 在索引上设置index.mapping.single_type: true将启用单索引中的单一类型行为该行为将在6.0版本中强制执行。作为Elasticsearch 5.6的一部分用于父子关系的新字段在新建的索引中可用。Elasticsearch 6.x 在5.x中创建的索引将在6.x中继续像5.x中一样工作。在6.x中创建的索引仅允许每个索引一个类型可以使用任何名称作为类型但每个索引只能有一个类型。推荐的类型名称是_doc以便在7.0中索引API具有与其在路径中的路径相同的路径PUT {index}/_doc/{id}和POST {index}/_doc。_type名称不再与_id组合以生成_uid字段。_uid字段已成为_id字段的别名。新索引不再支持旧样式的父子关系应使用新的join字段。_default_映射类型已被弃用。在6.8版本中索引创建、索引模板和映射API支持查询字符串参数include_type_name该参数指示请求和响应是否应包含类型名称。默认值为true应显式设置为准备升级到7.0版本。不设置include_type_name会导致弃用警告。没有明确类型的索引将使用虚拟类型名称_doc。Elasticsearch 7.x 在请求中指定类型已被弃用。例如在7.0中索引文档不再需要文档类型。新的索引API是PUT {index}/_doc/{id}对于显式id和POST {index}/_doc对于自动生成的id。请注意在7.0版本中_doc是路径的永久部分代表端点名称而不是文档类型。索引创建、索引模板和映射API中的include_type_name参数将默认为false。设置该参数将导致弃用警告。_default_映射类型已被移除。**
Elasticsearch 8.x** 不再支持在请求中指定类型。include_type_name参数已被移除。
将多类型索引迁移到单类型的方法
Reindex API可以用于将多类型索引转换为单类型索引。以下示例适用于Elasticsearch 5.6或Elasticsearch 6.x。在6.x中无需指定index.mapping.single_type因为它是默认设置。
按文档类型创建索引
首先将twitter索引分成tweets索引和users索引
PUT users
{settings: {index.mapping.single_type: true},mappings: {_doc: {properties: {name: {type: text},user_name: {type: keyword},email: {type: keyword}}}}
}PUT tweets
{settings: {index.mapping.single_type: true},mappings: {_doc: {properties: {content: {type: text},user_name: {type: keyword},tweeted_at: {type: date}}}}
}POST _reindex
{source: {index: twitter,type: user},dest: {index: users,type: _doc}
}POST _reindex
{source: {index: twitter,type: tweet},dest: {index: tweets,type: _doc}
}自定义类型字段
下一个示例添加了自定义类型字段并将其设置为原始_type的值。还将类型添加到_id中以防有冲突的ID具有不同的类型的文档
PUT new_twitter
{mappings: {_doc: {properties: {type: {type: keyword},name: {type: text},user_name: {type: keyword},email: {type: keyword},content: {type: text},tweeted_at: {type: date}}}}
}POST _reindex
{source: {index: twitter},dest: {index: new_twitter},script: {source: ctx._source.type ctx._type;ctx._id ctx._type - ctx._id;ctx._type _doc;}
}7.0版本的无类型API
在Elasticsearch 7.0中每个API都支持无类型请求指定类型将产生弃用警告。
无类型API即使目标索引包含自定义类型也能正常工作。例如如果索引具有自定义类型名称my_type我们可以使用无类型的索引调用添加文档并使用无类型的获取调用加载文档。
索引API
索引创建、索引模板和映射API支持一个新的include_type_name URL参数该参数指定请求和响应中的映射定义是否包含类型名称。该参数在6.8版本中默认为true以匹配使用映射中的类型名称的7.0之前的行为。在7.0版本中默认为false并将在8.0版本中移除。为了避免在6.8中出现弃用警告可以在6.8版本中显式设置该参数为true或false。在7.0中设置include_type_name参数将产生弃用警告。
文档API
在7.0中文档API必须使用{index}/_doc路径进行调用以实现自动生成的_id以及{index}/_doc/{id}以指定显式的id。
搜索API
在调用搜索API如_search、_msearch或_explain时不应在URL中包含类型。此外在查询、聚合或脚本中不应再使用_type字段。
响应中的类型
文档和搜索API将继续在响应中返回_type键以避免破坏响应解析。但该键被视为弃用不再应引用。在8.0版本中将完全从响应中删除类型。
请注意当使用弃用的类型API时索引的映射类型将正常返回但无类型API将在响应中始终返回虚拟类型_doc即使映
射中的类型不是_doc。如果您需要直接访问索引的映射类型请避免使用无类型API而是使用_default_ API或从节点的_mappings endpoint检索索引的映射。
总之Elasticsearch在7.0版本中已经不再支持映射类型。原来使用类型的功能现在可以通过单索引多类型、自定义类型字段或无类型的API请求来实现。这些变化使Elasticsearch的数据建模更加灵活和清晰同时减少了数据稀疏性和字段类型冲突的问题。
元数据字段 Metadata fields
元数据字段是与每个文档相关的信息例如 _index索引、_type映射类型和 _id文档标识等。在创建映射类型时有些元数据字段的行为可以进行自定义。
身份元数据字段
_index索引文档所属的索引。_type映射类型文档的映射类型。_id文档标识文档的唯一标识符。
文档源元数据字段
_source_源包含文档主体的原始 JSON 数据。_size_大小由 mapper-size 插件提供的 _source 字段的大小以字节为单位。
文档计数元数据字段
_doc_count_文档计数用于存储文档代表的预聚合数据的自定义字段。
索引元数据字段
_field_names_字段名称文档中包含非空值的所有字段。_ignored_已忽略由于 ignore_malformed 而在索引时被忽略的文档中的所有字段。
路由元数据字段
_routing_路由自定义路由值用于将文档路由到特定的分片。
其他元数据字段
_meta_元数据应用程序特定的元数据。_tier_层级文档所属索引的当前数据层级首选项。
_doc_count field 文档计数字段 _bucket aggregations桶聚合总是返回一个名为 doc_count 的字段显示了每个桶中聚合和分区的文档数量。计算 doc_count 的值非常简单对于每个收集到的文档doc_count 会递增 1。
虽然这种简单的方法在计算针对单个文档的聚合时有效但它无法准确表示存储了预聚合数据例如直方图或 aggregate_metric_double 字段的文档因为一个汇总字段可能代表多个文档。
为了正确计算处理预聚合数据时的文档数量我们引入了一个名为 _doc_count 的元数据字段类型。_doc_count 必须始终是表示单个汇总字段中聚合的文档数量的正整数。
当将 _doc_count 字段添加到文档中时所有桶聚合将尊重其值并将桶的 doc_count 递增字段的值。如果文档不包含任何 _doc_count 字段默认情况下 _doc_count 1。
一个 _doc_count 字段只能在一个文档中存储一个正整数。不允许嵌套数组。
如果文档不包含 _doc_count 字段聚合器将递增 1这是默认行为。
示例
以下的创建索引 API 请求创建了一个具有以下字段映射的新索引
my_histogram用于存储百分位数数据的直方图字段 my_text用于存储直方图标题的关键字字段
PUT my_index
{mappings : {properties : {my_histogram : {type : histogram},my_text : {type : keyword}}
}以下的索引 API 请求存储了两个直方图的预聚合数据histogram_1 和 histogram_2。
PUT my_index/_doc/1
{my_text : histogram_1,my_histogram : {values : [0.1, 0.2, 0.3, 0.4, 0.5],counts : [3, 7, 23, 12, 6]},_doc_count: 45
}PUT my_index/_doc/2
{my_text : histogram_2,my_histogram : {values : [0.1, 0.25, 0.35, 0.4, 0.45, 0.5],counts : [8, 17, 8, 7, 6, 2]},_doc_count: 62
}_doc_count 字段必须是存储用于生成每个直方图的文档数量的正整数。
如果我们在 my_index 上运行以下的 terms 聚合
GET /_search
{aggs : {histogram_titles : {terms : { field : my_text }}}
}我们将得到以下响应
{...aggregations : {histogram_titles : {doc_count_error_upper_bound: 0,sum_other_doc_count: 0,buckets : [{key : histogram_2,doc_count : 62},{key : histogram_1,doc_count : 45}]}}
}这个响应显示了每个直方图标题的文档数量正确地反映了存储了 _doc_count 字段的文档的预聚合数据。 _field_names 字段名称 _field_names 字段用于索引包含任何非空值的字段的名称这些字段包含在文档中。此字段曾用于 exists 查询以查找具有或不具有特定字段的非空值的文档。
现在_field_names 字段仅索引已禁用 doc_values 和 norms 的字段的名称。对于启用了 doc_values 或 norm 的字段exists 查询仍然可用但不会使用 _field_names 字段。
禁用 _field_names 禁用 _field_names 已被弃用并将在未来的主要版本中移除。
通常情况下禁用 _field_names 不是必要的因为它不再像以前那样带有索引开销。如果您有许多已禁用 doc_values 和 norms 的字段且不需要使用这些字段执行 exists 查询您可以通过将以下内容添加到映射中来禁用 _field_names
PUT tweets
{mappings: {_field_names: {enabled: false}}
}这将禁用 _field_names 字段。 _ignored 字段 _ignored 字段用于索引和存储文档中在索引文档时被忽略的每个字段的名称。这可以出现在字段格式不正确且已启用 ignore_malformed 时或者当关键字字段的值超出其可选的 ignore_above 设置时。
此字段可通过 term、terms 和 exists 查询进行搜索并作为搜索命中的一部分返回。
例如以下查询将匹配所有包含一个或多个被忽略字段的文档
GET _search
{query: {exists: {field: _ignored}
}类似地以下查询将查找所有在索引时被忽略的文档的 timestamp 字段
GET _search
{query: {term: {_ignored: timestamp}
}这将找到所有在索引时被忽略的 timestamp 字段的文档。 _id field 每个文档都有一个唯一标识符 _id用于唯一标识文档并且已被索引以便可以使用 GET API 或 ids 查询来查找文档。_id 可以在索引时分配或者可以由Elasticsearch生成一个唯一的 _id。此字段在映射中不可配置。
_id 字段的值可以在诸如 term、terms、match 和 query_string 之类的查询中访问。
示例文档
PUT my-index-000001/_doc/1
{text: 带有 ID 1 的文档
}PUT my-index-000001/_doc/2?refreshtrue
{text: 带有 ID 2 的文档
}GET my-index-000001/_search
{query: {terms: {_id: [ 1, 2 ] }}
}通过 _id 字段进行查询也可参见 ids 查询
_id 字段受限于不可用于聚合、排序和脚本的限制。如果需要在 _id 字段上进行排序或聚合建议将 _id 字段的内容复制到启用了 doc_values 的另一个字段中。
_id 字段的大小限制为 512 字节更大的值将被拒绝。 _index field 在跨多个索引执行查询时有时希望添加与特定索引的文档相关的查询子句。_index 字段允许匹配文档被索引的索引。其值可以在某些查询和聚合以及在排序或脚本中访问
PUT index_1/_doc/1
{text: 在索引 1 中的文档
}PUT index_2/_doc/2?refreshtrue
{text: 在索引 2 中的文档
}GET index_1,index_2/_search
{query: {terms: {_index: [index_1, index_2] }},aggs: {indices: {terms: {field: _index, size: 10}}},sort: [{_index: { order: asc}}],script_fields: {index_name: {script: {lang: painless,source: doc[_index] }}}
}使用 _index 字段进行查询
在 _index 字段上进行聚合
在 _index 字段上进行排序
在脚本中访问 _index 字段
_index 字段在虚拟上是可用的它不会被添加到 Lucene 索引作为实际字段。这意味着您可以在术语或术语查询中使用 _index 字段或任何重写为术语查询的查询如 match、query_string 或 simple_query_string 查询以及前缀和通配符查询。但是它不支持正则表达式和模糊查询。
对 _index 字段的查询除了具体索引名称外还可以接受索引别名。
在指定远程索引名称时如 cluster_1:index_3查询必须包含分隔字符 :。例如对 cluster_:index_3 的通配符查询将匹配来自远程索引的文档。然而对 clusterindex_1 的查询仅匹配本地索引因为没有分隔符。此行为与远程索引名称的通常解析规则相一致。
_meta field 映射类型可以关联自定义元数据。Elasticsearch 并不直接使用这些元数据但可以用来存储特定于应用程序的元数据例如文档所属的类别
PUT my-index-000001
{mappings: {_meta: { class: MyApp::User,version: {min: 1.0,max: 1.3}}}
}可以使用 GET mapping API 检索此 _meta 信息。
可以使用 update mapping API 在现有类型上更新 _meta 字段
PUT my-index-000001/_mapping
{_meta: {class: MyApp2::User3,version: {min: 1.3,max: 1.5}}
}这使您可以随时更新映射类型的 _meta 元数据。这对于存储关于文档的附加信息或自定义应用程序数据非常有用。
_routing field
文档通过以下公式被路由到索引中的特定分片
routing_factor num_routing_shards / num_primary_shards shard_num (hash(_routing) % num_routing_shards) / routing_factor 其中num_routing_shards 是索引设置 index.number_of_routing_shards 的值num_primary_shards 是索引设置 index.number_of_shards 的值。
默认情况下_routing 的值是文档的 _id。可以通过为每个文档指定自定义的 _routing 值来实现自定义路由模式。例如
PUT my-index-000001/_doc/1?routinguser1refreshtrue
{title: 这是一个文档
}此文档使用 user1 作为其 _routing 值而不是其 ID。
在获取、删除或更新文档时需要提供相同的 _routing 值。
可以在查询中访问 _routing 字段的值
GET my-index-000001/_search
{query: {terms: {_routing: [ user1 ] }}
}使用 _routing 字段进行查询
数据流不支持自定义路由。取而代之的是将查询发送到数据流的适当后备索引。
使用自定义路由进行搜索
自定义路由可以降低搜索的影响。与其将搜索请求广播到索引中的所有分片不如将请求发送到与特定路由值或值匹配的分片
GET my-index-000001/_search?routinguser1,user2
{query: {match: {title: document}}
}此搜索请求仅在与 user1 和 user2 路由值关联的分片上执行。
使路由值为必需项
在使用自定义路由时重要的是在索引、获取、删除或更新文档时提供路由值。忘记路由值可能导致文档被索引到多个分片上。作为一种保障措施可以配置 _routing 字段使自定义路由值对所有 CRUD 操作都是必需的
PUT my-index-000002
{mappings: {_routing: {required: true }}
}在此示例中对于所有文档都要求路由。
唯一的 ID 与自定义路由
当索引文档时指定自定义 _routing 时不能保证 _id 在索引中的所有分片上是唯一的。实际上如果使用不同的 _routing 值索引具有相同 _id 的文档可能会出现在不同的分片上。
由用户负责确保 _id 在索引中是唯一的。
路由到索引分区
可以配置索引以使自定义路由值进入分片的子集而不是单个分片。这有助于减轻出现不平衡集群的风险同时仍然减小了搜索的影响。
要启用此功能需要在索引创建时提供 index.routing_partition_size 的索引级设置。随着分区大小的增加数据将更均匀地分布但每个请求将不得不搜索更多的分片。
启用此设置后计算分片的公式如下
routing_value hash(_routing) hash(_id) % routing_partition_size shard_num (routing_value % num_routing_shards) / routing_factor 即_routing 字段用于计算索引中的一组分片然后使用 _id 来选择该组内的分片。
为启用此功能index.routing_partition_size 的值应大于 1 且小于 index.number_of_shards。
一旦启用分区索引将具有以下限制
不能在其中创建具有关联字段关系的映射。 索引内的所有映射必须将 _routing 字段标记为必需的。
_source field _source 字段包含在索引时传递的原始 JSON 文档正文。_source 字段本身不被索引因此不可搜索但它被存储以便在执行获取或搜索等提取请求时可以返回。
禁用 _source 字段 虽然_source字段非常有用但它在索引中会产生存储开销。因此可以通过以下方式禁用它
PUT my-index-000001
{mappings: {_source: {enabled: false}}
}在禁用 _source 字段之前请考虑一下后果。如果_source字段不可用将不支持许多功能包括
update、update_by_query 和 reindex API。即时高亮显示。从一个 Elasticsearch 索引重新索引到另一个索引的能力无论是更改映射或分析还是将索引升级到新的主要版本。通过查看索引时使用的原始文档来调试查询或聚合的能力。可能在未来自动修复索引损坏的能力。
如果担心磁盘空间可以增加压缩级别而不是禁用 _source。
包括/排除字段从 _source 中 一个专家级的功能是在文档被索引后、但在 _source 字段存储之前可以修剪 _source 字段的内容。
从 _source 中删除字段与禁用 _source 具有类似的缺点特别是不能将文档从一个 Elasticsearch 索引重新索引到另一个索引。考虑使用源字段过滤而不是删除字段。
可以使用 includes/excludes 参数还接受通配符来进行如下设置
PUT logs
{mappings: {_source: {includes: [*.count,meta.*],excludes: [meta.description,meta.other.*]}}
}这些字段将从存储的 _source 字段中删除。
即使这些字段不在存储的 _source 中我们仍然可以在该字段上进行搜索。 _tier field
在跨多个索引执行查询时有时希望定位存储在给定数据层节点上的索引data_hot、data_warm、data_cold 或 data_frozen。_tier 字段允许匹配文档被索引到的索引的 tier_preference 设置。首选值可以在某些查询中访问
PUT index_1/_doc/1
{text: 在索引 1 中的文档
}PUT index_2/_doc/2?refreshtrue
{text: 在索引 2 中的文档
}GET index_1,index_2/_search
{query: {terms: {_tier: [data_hot, data_warm] }}
}使用 _tier 字段进行查询
通常查询将使用 terms 查询列出感兴趣的层级但您可以在任何被重写为术语查询的查询中使用 _tier 字段如 match、query_string、term、terms 或 simple_query_string 查询以及前缀和通配符查询。然而它不支持正则表达式和模糊查询。
索引的 tier_preference 设置是首选层级的逗号分隔列表按照首选层级主机索引的顺序排列首选层级在列表中首先列出然后是可能的多个备选选项。查询匹配只考虑首选项列表的第一个值。
映射参数 Mapping parameters
Mapping parameters | Elasticsearch Guide [7.17] | Elastic 以下是常用的一些映射参数 analyzer: 用于指定分析器用于文本字段的文本分析。 boost: 用于调整字段的相关性得分可以提高或降低字段的权重。 doc_values: 指示是否在字段上启用 doc_values以便进行聚合和排序。 dynamic: 控制字段是否动态映射允许 Elasticsearch 自动检测字段类型。 enabled: 控制字段是否被启用或禁用可以用于临时禁用字段而不需要删除映射。 index: 控制字段是否被索引可以设置为 true、false 或 null使用默认设置。 store: 控制字段是否被存储以便在检索文档时获取原始值。 norms: 控制字段的归一化设置用于评分计算。 properties: 用于定义对象字段的子字段。 search_analyzer: 用于指定搜索时使用的分析器不同于索引时的分析器。 similarity: 用于指定字段的相似性设置影响相关性得分。
映射限制
以下是用于限制字段映射数量以防止映射爆炸的设置 index.mapping.total_fields.limit这是索引中字段的最大数量。字段和对象映射以及字段别名都计入这一限制。默认值为1000。此限制旨在防止映射和搜索变得过大。较高的值可能导致性能下降和内存问题尤其是在负载较高或资源较少的集群中。如果您增加此设置建议同时增加indices.query.bool.max_clause_count设置该设置限制了查询中的布尔子句的最大数量。 index.mapping.depth.limit这是字段的最大深度以内部对象数量来衡量。例如如果所有字段都在根对象级别定义那么深度为1。如果存在一个对象映射则深度为2依此类推。默认值为20。 index.mapping.nested_fields.limit这是索引中不同嵌套映射的最大数量。嵌套类型应仅在特殊情况下使用当需要独立查询对象数组时。为防止不良设计的映射此设置限制了每个索引中唯一嵌套类型的数量。默认值为50。 index.mapping.nested_objects.limit这是单个文档中包含的所有嵌套 JSON 对象的最大数量跨所有嵌套类型。此限制有助于防止文档包含过多嵌套对象时发生内存不足错误。默认值为10000。 index.mapping.field_name_length.limit此设置用于限制字段名称的最大长度。通常情况下不需要设置此设置因为默认设置是足够的除非用户开始添加具有非常长名称的大量字段。默认值是Long.MAX_VALUE没有限制。 index.mapping.dimension_fields.limit技术预览此功能处于技术预览阶段可能在将来的版本中更改或删除。它是 Elastic 内部使用的设置。
删除映射类型
从Elasticsearch 7.0.0开始不再支持默认映射类型_default_ mapping type。在6.x中创建的索引将在Elasticsearch 6.x中继续像以前一样运行。在7.0版本的API中映射类型被弃用并在索引创建、映射添加、映射获取、模板添加、模板获取以及字段映射获取等API中进行了破坏性更改。
什么是映射类型
自Elasticsearch首次发布以来每个文档都存储在单个索引中并分配给一个映射类型mapping type。映射类型用于表示要索引的文档或实体的类型例如Twitter索引可能包括用户类型user type和推文类型tweet type。
每个映射类型可以拥有自己的字段。例如用户类型可能包括full_name字段、user_name字段和email字段而推文类型可以包括content字段、tweeted_at字段和与用户类型相同的user_name字段。
每个文档都有一个名为_type的元数据字段其中包含类型名称。通过在URL中指定类型名称可以限制搜索仅在一个或多个类型中进行
GET twitter/user,tweet/_search
{query: {match: {user_name: kimchy}}
}_type字段与文档的_id组合生成_uid字段因此具有相同_id但不同类型的文档可以存在于单个索引中。
映射类型还用于建立文档之间的父子关系因此问题类型question的文档可以是答案类型answer的父文档。
为什么要移除映射类型
最初我们提到“索引”类似于SQL数据库中的“数据库”而“类型”等同于“表”。
这是一个不准确的类比它导致了错误的假设。在SQL数据库中各个表是相互独立的。一个表中的列与另一个表中具有相同名称的列之间没有关联。但在映射类型中的字段却不同。
在Elasticsearch索引中具有相同名称的字段在内部由相同的Lucene字段支持。换句话说在上面的示例中用户类型中的user_name字段与推文类型中的user_name字段实际上存储在相同的字段中并且两个user_name字段必须在两个类型中具有相同的映射定义。
这可能会导致困扰例如当您希望在同一索引中的一个类型中将deleted字段设为日期字段而在另一个类型中将其设为布尔字段时。
此外将不具备共同字段或仅有少数共同字段的不同实体存储在同一个索引中会导致数据稀疏干扰Lucene有效压缩文档的能力。
出于这些原因我们决定从Elasticsearch中移除映射类型的概念。
映射类型的替代方案 按文档类型创建索引Index per document type 第一种替代方案是为每个文档类型创建一个单独的索引。而不是将推文和用户存储在单个twitter索引中您可以在tweets索引中存储推文在users索引中存储用户。这些索引是完全独立的因此不会在不同索引之间发生字段类型冲突。此方法有两个好处数据更有可能是密集的因此可以受益于Lucene中使用的压缩技术全文搜索中用于评分的术语统计更可能准确因为同一索引中的所有文档代表单个实体。每个索引可以根据其包含的文档数量适当设置主分片的数量。 自定义类型字段Custom type field 当然每个群集中的主分片数量存在限制因此您可能不希望为只包含少数几千个文档的集合浪费整个主分片。在这种情况下您可以实现自定义类型字段它将类似于旧的_type。例如上面的用户/推文示例原本的工作流如下 PUT twitter
{mappings: {user: {properties: {name: { type: text },user_name: { type: keyword },email: { type: keyword }}},tweet: {properties: {content: { type: text },user_name: { type: keyword },tweeted_at: { type: date }}}}
}PUT twitter/user/kimchy
{name: Shay Banon,user_name: kimchy,email: shaykimchy.com
}PUT twitter/tweet/1
{user_name: kimchy,tweeted_at: 2017-10-24T09:00:00Z,content: Types are going away
}GET twitter/tweet/_search
{query: {match: {user_name: kimchy}}
}您可以通过添加自定义类型字段来实现相同的目标如下所示 PUT twitter
{mappings: {_doc: {properties: {type: { type: keyword
}, “name”: { “type”: “text” }, “user_name”: { “type”: “keyword” }, “email”: { “type”: “keyword” }, “content”: { “type”: “text” }, “tweeted_at”: { “type”: “date” } } } } }
PUT twitter/_doc/user-kimchy
{type: user, name: Shay Banon,user_name: kimchy,email: shaykimchy.com
}PUT twitter/_doc/tweet-1
{type: tweet, user_name: kimchy,tweeted_at: 2017-10-24T09:00:00Z,content: Types are going away
}GET twitter/_search
{query: {bool: {must: {match: {user_name: kimchy}},filter: {match: {type: tweet }}}}
}
显式的类型字段取代了隐式的_type字段。无映射类型的父子关系Parent/Child without mapping types 以前父子关系是通过将一个映射类型指定为父类型将一个或多个其他映射类型指定为子类型来表示的。没有映射类型我们不能再使用这种语法。父子关系特性将继续像以前一样运行只是表示文档之间关系的方式已更改为使用新的join字段。
映射类型移除的时间表
Elasticsearch 5.6.0 在索引上设置index.mapping.single_type: true将启用单索引中的单一类型行为该行为将在6.0版本中强制执行。作为Elasticsearch 5.6的一部分用于父子关系的新字段在新建的索引中可用。Elasticsearch 6.x 在5.x中创建的索引将在6.x中继续像5.x中一样工作。在6.x中创建的索引仅允许每个索引一个类型可以使用任何名称作为类型但每个索引只能有一个类型。推荐的类型名称是_doc以便在7.0中索引API具有与其在路径中的路径相同的路径PUT {index}/_doc/{id}和POST {index}/_doc。_type名称不再与_id组合以生成_uid字段。_uid字段已成为_id字段的别名。新索引不再支持旧样式的父子关系应使用新的join字段。_default_映射类型已被弃用。在6.8版本中索引创建、索引模板和映射API支持查询字符串参数include_type_name该参数指示请求和响应是否应包含类型名称。默认值为true应显式设置为准备升级到7.0版本。不设置include_type_name会导致弃用警告。没有明确类型的索引将使用虚拟类型名称_doc。Elasticsearch 7.x 在请求中指定类型已被弃用。例如在7.0中索引文档不再需要文档类型。新的索引API是PUT {index}/_doc/{id}对于显式id和POST {index}/_doc对于自动生成的id。请注意在7.0版本中_doc是路径的永久部分代表端点名称而不是文档类型。索引创建、索引模板和映射API中的include_type_name参数将默认为false。设置该参数将导致弃用警告。_default_映射类型已被移除。**
Elasticsearch 8.x** 不再支持在请求中指定类型。include_type_name参数已被移除。
将多类型索引迁移到单类型的方法
Reindex API可以用于将多类型索引转换为单类型索引。以下示例适用于Elasticsearch 5.6或Elasticsearch 6.x。在6.x中无需指定index.mapping.single_type因为它是默认设置。
按文档类型创建索引
首先将twitter索引分成tweets索引和users索引
PUT users
{settings: {index.mapping.single_type: true},mappings: {_doc: {properties: {name: {type: text},user_name: {type: keyword},email: {type: keyword}}}}
}PUT tweets
{settings: {index.mapping.single_type: true},mappings: {_doc: {properties: {content: {type: text},user_name: {type: keyword},tweeted_at: {type: date}}}}
}POST _reindex
{source: {index: twitter,type: user},dest: {index: users,type: _doc}
}POST _reindex
{source: {index: twitter,type: tweet},dest: {index: tweets,type: _doc}
}自定义类型字段
下一个示例添加了自定义类型字段并将其设置为原始_type的值。还将类型添加到_id中以防有冲突的ID具有不同的类型的文档
PUT new_twitter
{mappings: {_doc: {properties: {type: {type: keyword},name: {type: text},user_name: {type: keyword},email: {type: keyword},content: {type: text},tweeted_at: {type: date}}}}
}POST _reindex
{source: {index: twitter},dest: {index: new_twitter},script: {source: ctx._source.type ctx._type;ctx._id ctx._type - ctx._id;ctx._type _doc;}
}7.0版本的无类型API
在Elasticsearch 7.0中每个API都支持无类型请求指定类型将产生弃用警告。
无类型API即使目标索引包含自定义类型也能正常工作。例如如果索引具有自定义类型名称my_type我们可以使用无类型的索引调用添加文档并使用无类型的获取调用加载文档。
索引API
索引创建、索引模板和映射API支持一个新的include_type_name URL参数该参数指定请求和响应中的映射定义是否包含类型名称。该参数在6.8版本中默认为true以匹配使用映射中的类型名称的7.0之前的行为。在7.0版本中默认为false并将在8.0版本中移除。为了避免在6.8中出现弃用警告可以在6.8版本中显式设置该参数为true或false。在7.0中设置include_type_name参数将产生弃用警告。
文档API
在7.0中文档API必须使用{index}/_doc路径进行调用以实现自动生成的_id以及{index}/_doc/{id}以指定显式的id。
搜索API
在调用搜索API如_search、_msearch或_explain时不应在URL中包含类型。此外在查询、聚合或脚本中不应再使用_type字段。
响应中的类型
文档和搜索API将继续在响应中返回_type键以避免破坏响应解析。但该键被视为弃用不再应引用。在8.0版本中将完全从响应中删除类型。
请注意当使用弃用的类型API时索引的映射类型将正常返回但无类型API将在响应中始终返回虚拟类型_doc即使映
射中的类型不是_doc。如果您需要直接访问索引的映射类型请避免使用无类型API而是使用_default_ API或从节点的_mappings endpoint检索索引的映射。
总之Elasticsearch在7.0版本中已经不再支持映射类型。原来使用类型的功能现在可以通过单索引多类型、自定义类型字段或无类型的API请求来实现。这些变化使Elasticsearch的数据建模更加灵活和清晰同时减少了数据稀疏性和字段类型冲突的问题。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/85341.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!