前言:在elasticsearch中,结合业务场景与数据值的特点,在索引的字段类型配置中设置合理的字段类型是十分有必要的。例如:我们将field类型设置为text,配合分词器,我们可以实现全文检索。如果将field类型设置为keyword,我们就可以对数据实现精确查询聚合排序。
可以存储编码为base64的编码的二进制值。
使用binary存储字段数据后,数据只是以二进制的形式存储于elasticsearch中。在我们操作数据时,并不能对数据进行检索,聚合或分析。如果需要对binary类型的字段进行数据则需要结合其他索引字段或对binary字段的数据进行反序列化来实现。
布尔类型,用于存储true或false;
属于keyword字段族,其中包含了keyword,constant_keyword和wildcard;
用于存储结构化数据。使用keyword类型存储的数据不会被分词,而是将整个字段值作为一个关键字进行处理。例如:我们日常使用中的邮箱地址,手机号,用户ID,等数据都可以用keyword类型进行存储。
keyword类型由于是将整个字段值当做一个关键字进行处理,所以不适用于全文检索,模糊匹配等需要对文本内容进行分析的场景。
用于存储常量关键字。constant_keyword字段类型的值在所有文档中都是相同的,它不会根据文档内容而变化。主要在索引中存储固定的元数据或者标记。
通配符字段类型,主要用于存储准备使用通配符形式检索的字段数据。使用该字段类型,我们可以通过通配符的形式对数据进行检索。例如:使用(*或?)来匹配具有特定模式的文本。
模糊搜索:我们可以在搜索数据时使用通配符的形式对数据进行模糊匹配。来匹配包含搜索关键字的数据。例如:使用"success*"进行搜索,那么搜索结果则会返回"success","successful","successor"等以"success"关键字开头的文本。
多字符匹配:我们可以使用?来匹配一个字符。例如我们使用"he?p"关键字进行搜索,则会匹配"help","heap"等符合匹配规则的数据。
高级搜索:可以使用通配符根据特定规则对数据进行匹配,例如根据规则匹配URL,文件路径等。
由于wildcard使用的是字符串匹配这种方式对数据进行查询,在大规模数据集索引中,容易产生慢查询,造成性能问题。因此,在使用上仍需考虑其他搜索方式。
具体可以参考我的另一篇文章:https://cloud.tencent.com/developer/article/2357251
数值字段类型,其中包含integer,long,double,float,byte等长整型,单双精度浮点型数值字段类型。
主要用于我们存储数值类型数据,例如:金额,long类型时间戳,统计指标数值,商品数量等。根据字段值大小,选择合适的数值字段类型,能够有效的节约磁盘存储空间,提高存储效率与数据检索效率。需要注意的是,elasticsearch在进行存储空间优化时主要根据存储的实际数值来进行存储优化,并不是根据我们选择的字段类型进行针对性优化。
integer
或浮点数类型,例如:float
或double
对数据进行存储,这些字段类型适合我们存储,例如:订单金额,商品库存等数据。对现有字段定义别名。当对字段进行别名定义后,我们也可以通过别名来对字段进行检索。在搜索当中所有的请求都可以使用别名,不论是精确查询还是聚合查询,都可以使用字段的别名。
我们可以通过以下这个样例,对字段别名进行定义,并进行搜索。
PUT trips
{
"mappings": {
"properties": {
"distance": {
"type": "long"
},
"route_length_miles": {
"type": "alias",
"path": "distance"
},
"transit_mode": {
"type": "keyword"
}
}
}
}
GET _search
{
"query": {
"range" : {
"route_length_miles" : {
"gte" : 39
}
}
}
}
用于存储json嵌套对象,当我们需要将整个json以对象的形式进行存储时,可以选择该类型。
用于存储json对象数据。通过使用该类型,将整个json扁平化的映射为一个字段。然后解析出json中的键值对。一般多用于存储含有大量字段或未知字段的json对象。使用该类型存储的json数据只允许使用基础查询。
在以下示例中,我们将bug_reports索引的labels设置为flattened类型。然后我们在手动插入一条数据,可以看到在labels字段中,我们手动插入了一条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
}
}
}
在下面的样例中,在我们可以直接对labels字段,以"labels":"urgent"为条件,直接进行精确查询;也可以用"labels.release":"v1.3.0" json内部某个子字段作为查询条件进行精确查询。
POST bug_reports/_search
{
"query": {
"term": {"labels": "urgent"}
}
}
POST bug_reports/_search
{
"query": {
"term": {"labels.release": "v1.3.0"}
}
}
当字段设置为flattened类型后,仅支持以下查询方式。
term
, terms
, terms_set
prefix
range
match
, multi_match
query_string
,simple_query_string
exists
专门用于存储嵌套对象的字段类型。如果我们需要存储内部包含了大量键值对的json对象或其他嵌套对象数据时,我们可以使用Nested类型。反之建议使用flattened字段类型。对于嵌套字段类型数据的存储与查询所消耗的资源相较于其他字段类型是更加高昂的。所以需要在存储嵌套对象数据时选择合适的字段类型。
在以下样例中,我们将user字段的类型设置为了Nested。然后在该字段,插入了一个存储json对象的数组。
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" }}
]
}
}
}
}
}
当我们使用Nested类型时,嵌套对象中的子字段在查询时可以进行聚合排序等操作。
连接数据类型:主要用于在同一索引的文档中,创建父/子关系,通过添加Join字段,我们可以将文档定义为父级文档和子级文档,来表示文档建的关系。当我们的数据存在着一对多的关系时,我们就可以通过Join类型来为这些数据创建父子关系。例如:文章主体与文章评论之间的关系。其中文章是父级文档,评论是子级文档。便于我们对有父子关系或嵌套关系的数据进行标识与建模。
在以下样例中:我们在创建my-index-000001索引时,添加了一个Join字段类型的my_join_field字段,关系为"问题与答案"。我们插入了id为1的问题。同时创建了id为3的答案。我们指定了其父级文档的id为1。此时我们就可以理解为id为3的这条数据是id为1这条数据的子文档。也就是id为3的这条数据是id为1这条数据中所描述问题的答案。
PUT my-index-000001
{
"mappings": {
"properties": {
"my_id": {
"type": "keyword"
},
"my_join_field": {
"type": "join",
"relations": {
"question": "answer"
}
}
}
}
}
PUT my-index-000001/_doc/1?refresh
{
"my_id": "1",
"text": "This is a question",
"my_join_field": "question"
}
PUT my-index-000001/_doc/3?routing=1&refresh
{
"my_id": "3",
"text": "This is an answer",
"my_join_field": {
"name": "answer",
"parent": "1"
}
}
结构化数据类型,主要包含range,ip,version,murmur3.
范围字段类型:用于表示字段的上限与下限的范围。例如:时间范围10月1日~10月15日。数字范围0~9。
其中包含:integer_range,float_range,long_range,double_range,date_range,ip_range
在以下样例中,我们在range_index中将expected_attendees设置为integer_range,将time_frame设置为date_range。然后我们插入了一条expected_attendees的大于等于10,小于20,time_frame大于等于"2015-10-31 12:00:00",小于等于"2015-11-01"的数据。
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"
}
}
然后我们可以在查询时,以range字段为条件,根据传入的value直接进行范围匹配,判断该值是否在range类型数据的范围内。
GET range_index/_search
{
"query" : {
"term" : {
"expected_attendees" : {
"value": 12
}
}
}
}
ip类型:主要用于存储IPV4,IPV6类型的IP数据。
版本类型:主要用于记录软件的版本。
哈希类型:用于存储计算中的hash值。
murmur3 哈希函数是一种快速、高效的哈希算法,用于将数据转换为固定长度的哈希值。
murmur3字段类型不适合直接存储元数据。只存储哈希值。
聚合字段类型:主要包含aggregate_mertric_double,histogram。
histogram 字段类型:主要用于存储和分析数值数据的分布情况。它将数值范围划分为桶(buckets),并统计每个桶中的文档数量。
文本字段类型:主要用于存储需要进行全文检索的数据。例如:文档内容,商品简介等信息。在搜索时需要配合分词器使用。分词器会根据词典与分词算法对文本进行切分,将一大段文本切分为若干个词项。当我们使用全文检索时,便于返回相关的结果。text字段不会用于聚合,大部分情况下也不会用于排序场景。
使用以下方式,我们可以将full_name的字段类型设置为text。此时该字段就可以被用于全文检索。
PUT my-index-000001
{
"mappings": {
"properties": {
"full_name": {
"type": "text"
}
}
}
}
当我们希望字段同时具备text与keyword的特点时,我们可以通过以下方式进行mapping设置:
PUT my-index-000001
{
"mappings": {
"properties": {
"my_field": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}
经纬度类型:主要用于存储经纬度坐标。一般多用于记录地理位置的经纬度。当我们需要针对数据绘制热力图,轨迹图等需要使用到经纬度坐标的图表时,我们就需要在索引中将相应字段设置为该类型。
我们可以使用以下方式将索引字段类型设置为geopoint。并提供了两种方式对经纬度类型的字段进行数据插入。
PUT my-index-000001
{
"mappings": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
PUT my-index-000001/_doc/1
{
"text": "Geopoint as an object",
"location": {
"lat": 41.12,
"lon": -71.34
}
}
PUT my-index-000001/_doc/2
{
"text": "Geopoint as a string",
"location": "41.12,-71.34"
}
在使用geopoint类型时,使用字符串形式插入坐标时,需要按照lat,lon排序。如果使用坐标数组形式插入数据,则需要按照lon,lat形式插入数据。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有