Elasticsearch:一些有趣的数据类型

Elastic 专栏收录该内容
494 篇文章 87 订阅

Elasticsearch 中的每个字段都有一个字段数据类型或字段类型。 此类型指示字段包含的数据类型(例如字符串或布尔值)及其预期用途。 例如,你可以将字符串索引到文本字段(text)和关键字(keyword)字段。 这样做的目的是,将分析文本字段值以进行全文搜索,而将关键字字符串保持原样以进行过滤和排序。

字段类型按 family 分组。 同一 family 中的类型支持相同的搜索功能,但可能具有不同的空间使用或性能特征。

当前,关键字(keyword)family ,它由 keyword,constant_keyword 和 wildcard 类型组成。 其他 familiy 可能只有一个字段类型。 例如,布尔 family 由一个字段类型组成:boolean。

有关数据类型的更多描述,可以在官方文档 找到。在今天的文章中,我们来介绍一些有趣的数据类型。有些我们已经在之前的文档中介绍过了。

 

unsigned_long

无符号长整数是一种数字字段类型,表示无符号的64位整数,最小值为0,最大值为(从0到18446744073709551615)。在 Java 编程中,最大的值为 long.MAX_VALUE = 9,223,372,036,854,775,807 (signed)。可以以数字或字符串形式导入无符号长整数,它们表示[0,18446744073709551615]范围内的整数值。 他们不能有小数部分。

PUT unsigned_long_test
{
  "mappings": {
    "properties": {
      "my_counter": {
        "type": "unsigned_long"
      }
    }
  }
}
POST /unsigned_long_test/_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}

我们可以使用如下的例子来进行查询:

GET unsigned_long_test/_search
{
  "query": {
    "range": {
      "my_counter": {
        "gte": 9223372036854775808
      }
    }
  }
}

上面的结果显示:

    "hits" : [
      {
        "_index" : "unsigned_long_test",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "my_counter" : "9223372036854775808"
        }
      },
      {
        "_index" : "unsigned_long_test",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "my_counter" : 18446744073709551614
        }
      },
      {
        "_index" : "unsigned_long_test",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 1.0,
        "_source" : {
          "my_counter" : 18446744073709551615
        }
      }
    ]
  }

这个大的数使用于银行或一些网络通信等需要一个大的 counter,每次交易会自动增加1。当 counter 达到最大值时,自动轮回到 0,这个很大的值不会轻易溢出。

 

Version

Version 字段类型是 keyword 字段的一种特殊形式,用于处理软件版本值并支持它们的专用优先级规则。 优先级是按照语义版本控制概述的规则定义的,例如,这意味着主要版本,次要版本和补丁版本部分按数字排序(即 “2.1.0” < “2.4.1” < “2.11.2”)并进行预发行 版本在发布版本之前进行排序(即 “1.0.0-alpha” <“ 1.0.0”)。

你索引一个 version 字段,如下所示

PUT version_index
{
  "mappings": {
    "properties": {
      "my_version": {
        "type": "version"
      }
    }
  }
}

PUT version_index/_bulk?refresh
{ "index": {} }
{ "my_version": "1.5.0-alpha" }
{ "index": {} }
{ "my_version": "1.2.5" }
{ "index": {} }
{ "my_version": "1.2.5-alpha2" }
{ "index": {} }
{ "my_version": "1.2.5-alpha2.beta" }
{ "index": {} }
{ "my_version": "1.2.5-alpha1" }
{ "index": {} }
{ "my_version": "1.2.5-beta1" }

我们做如下的搜索排序:

GET version_index/_search?filter_path=**.my_version
{
  "sort": [
    {
      "my_version": {
        "order": "desc"
      }
    }
  ]
}
{
  "hits" : {
    "hits" : [
      {
        "_source" : {
          "my_version" : "1.5.0-alpha"
        }
      },
      {
        "_source" : {
          "my_version" : "1.2.5"
        }
      },
      {
        "_source" : {
          "my_version" : "1.2.5-beta1"
        }
      },
      {
        "_source" : {
          "my_version" : "1.2.5-alpha2.beta"
        }
      },
      {
        "_source" : {
          "my_version" : "1.2.5-alpha2"
        }
      },
      {
        "_source" : {
          "my_version" : "1.2.5-alpha1"
        }
      }
    ]
  }
}

从上面可以看出来 1.2.5 发布版本比其它的 beta 及 alpha 版本要高。
 

Flatten

默认情况下,对象中的每个子字段都分别进行映射和索引。 如果事先不知道子字段的名称或类型,则将动态映射它们。

Flatten 类型提供了一种替代方法,其中将整个对象映射为单个字段。 对于给定的对象,Flatten 的映射将解析出其 leaf 值并将它们作为关键字索引到一个字段中。 然后可以通过简单的查询和汇总来搜索对象的内容。

如果你想了解更多,请参阅我之前的文章 “Elasticsearch:flattened 数据类型 (7.3 发行版新功能)”。

作为一个简单的例子,我们定一个 flattened 类型的索引:

PUT flattened
{
  "mappings": {
    "properties": {
      "labels": {
        "type": "flattened"
      }
    }
  }
}

POST flattened/_doc/1
{
  "labels": {
    "size": "x1",
    "color": "red",
    "type": "v-neck",
    "price": 25,
    "last_updated": 1614594536173
  }
}

POST flattened/_doc/2?refresh
{
  "labels": {
    "last_updated": 2
  }
}

在上面,我们为 flattened 索引创建了两个文档。让我们做如下的搜索:

GET flattened/_search
{
  "query": {
    "term": {
      "labels.color": "red"
    }
  }
}

上面返回数据:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.9530773,
    "hits" : [
      {
        "_index" : "flattened",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.9530773,
        "_source" : {
          "labels" : {
            "size" : "x1",
            "color" : "red",
            "type" : "v-neck",
            "price" : 25,
            "last_updated" : 1614594536173
          }
        }
      }
    ]
  }
}

因为所有的字段都被定义为 keyword,那么 timestamp 为 2 的比 1614594536173 要大。

GET flattened/_search?filter_path=**.last_updated
{
  "sort": [
    {
      "labels.last_updated": {
        "order": "desc"
      }
    }
  ]
}

上面的结果显示:

{
  "hits" : {
    "hits" : [
      {
        "_source" : {
          "labels" : {
            "last_updated" : 2
          }
        }
      },
      {
        "_source" : {
          "labels" : {
            "last_updated" : 1614594536173
          }
        }
      }
    ]
  }
}

Aggregate metric

为指标聚合存储预聚合数值。 Aggregate_metric_double 字段是一个对象,其中包含一个或多个以下指标子字段:min,max,sum 和 value_count。

当你在 aggregate_metric_double 字段上运行某些指标聚合时,该聚合将使用相关子字段的值。 例如,aggregate_metric_double字段上的 min 聚合返回所有 min 子字段的最小值。

重要:Aggregate_metric_double 字段为每个指标子字段存储一个数字 doc value。 不支持数组值。 min,max 和 sum 是 double 类型的值。 value_count 是一个正整数。

Aggregate_metric_double 字段的参数

metrics: (必需,字符串数组)要存储的指标子字段的数组。 每个值都对应一个指标聚合。 有效值为 minmaxsumvalue_count。 你必须至少指定一个值。
default_metric:(必需,字符串)默认指标子字段,用于不使用子字段的查询,脚本和聚合。 必须是来自指标数组的值。

我们先以一个例子来进行说明。首先创建一个叫做 sales_per_day 的索引:

PUT sales_per_day
{
  "mappings": {
    "properties": {
      "agg_metric": {
        "type": "aggregate_metric_double",
        "metrics": [ "min", "max", "value_count", "sum" ],
        "default_metric": "value_count"
      }
    }
  }
}

PUT sales_per_day/_doc/january
{
  "agg_metric": {
    "min": 13,
    "max": 34,
    "sum": 4653.00,
    "value_count": 234
  }
}

PUT sales_per_day/_doc/feburary?refresh
{
  "agg_metric": {
    "min": 5,
    "max": 28,
    "sum": 3124.34,
    "value_count": 260
  }
}

我们接下来可以做如下的搜索:

POST sales_per_day/_search?size=0
{
  "aggs": {
    "metric_min": {
      "min": {
        "field": "agg_metric"
      }
    },
    "metric_max": {
      "max": {
        "field": "agg_metric"
      }
    },
    "metric_value_count": {
      "value_count": {
        "field": "agg_metric"
      }
    },
    "metric_avg": {
      "avg": {
        "field": "agg_metric"
      }
    }
  }
}

上面搜索的结果是:

{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "metric_avg" : {
      "value" : 15.743603238866397
    },
    "metric_min" : {
      "value" : 5.0
    },
    "metric_max" : {
      "value" : 34.0
    },
    "metric_value_count" : {
      "value" : 494
    }
  }
}

我们可以看到两个文档的 max 字段中最大的值为 34,而最小的值为 5.0。value_count 变成了两个文档的 value_count 之合。而它的 metric_avg 其实就是两个文档的 sum 值相加,再除以 metric_value_count 的值。

 

dense_vector

density_vector 字段存储浮点值的 dense vectors。 向量中可以包含的最大维数不应超过 2048。density_vector 字段是单值字段。

你可以阅读我之前的文章 “Elasticsearch:基于 Vector 的打分

  • 1
    点赞
  • 2
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值