Flat 对象字段类型 #
在 Easysearch 中,您不需要在索引文档之前指定映射。如果您不指定映射,Easysearch 会使用动态映射自动映射文档中的每个字段及其子字段。当您摄取诸如日志之类的文档时,您可能事先不知道每个字段的子字段名称和类型。在这种情况下,动态映射所有新的子字段可能会快速导致"映射爆炸",其中不断增长的字段数量可能会降低集群的性能。
Flat 对象字段类型通过将整个 JSON 对象视为字符串来解决这个问题。可以使用标准的点路径表示法访问 JSON 对象中的子字段,但它们不会被索引成单独的字段以供快速查找。
点表示法(a.b)中的字段名最大长度为 2^24 − 1。
Flat 对象字段类型提供以下优势:
- 高效读取:获取性能类似于关键字字段。
- 内存效率:将整个复杂的 JSON 对象存储在一个字段中而不索引其所有子字段,可以减少索引中的字段数量。
- 空间效率:Easysearch 不会为 flat 对象中的子字段创建倒排索引,从而节省空间。
- 迁移兼容性:您可以将数据从支持类似 flat 字段的数据库系统迁移到 Easysearch。
当字段及其子字段主要用于读取而不是用作搜索条件时,应将字段映射为 flat 对象,因为子字段不会被索引。当对象具有大量字段或您事先不知道内容时,flat 对象非常有用。
Flat 对象支持带有和不带有点路径表示法的精确匹配查询。有关支持的查询类型的完整列表,请参见支持的查询。
在文档中搜索特定嵌套字段的值可能效率低下,因为它可能需要对索引进行完整扫描,这可能是一个昂贵的操作。
Flat 对象不支持:
- 特定类型的解析。
- 数值运算,如数值比较或数值排序。
- 文本分析。
- 高亮显示。
- 使用点表示法(a.b)的子字段聚合。
- 按子字段过滤。
支持的查询 #
Flat 对象字段类型支持以下查询:
- Term
- Terms
- Terms set
- Prefix
- Range
- Match
- Multi-match
- Query string
- Simple query string
- Exists
- Wildcard
限制 #
以下限制适用于 Easysearch 中的 flat 对象:
- Flat 对象不支持开放参数。
- 不支持使用 Painless 脚本和通配符查询来检索子字段的值。
使用 flat 对象 #
以下示例说明怎么将字段映射为 flat 对象、怎么索引带有 flat 对象字段的文档以及在这些文档中怎么去搜索 flat 对象的值。
首先,创建索引的映射,其中 issue
的类型为 flattened
:
PUT /test-index/
{
"mappings": {
"properties": {
"issue": {
"type": "flattened"
}
}
}
}
然后,索引两个带有 flat 对象字段的文档:
PUT /test-index/_doc/1
{
"issue": {
"number": "123456",
"labels": {
"version": "2.1",
"backport": [
"2.0",
"1.3"
],
"category": {
"type": "API",
"level": "enhancement"
}
}
}
}
PUT /test-index/_doc/2
{
"issue": {
"number": "123457",
"labels": {
"version": "2.2",
"category": {
"type": "API",
"level": "bug"
}
}
}
}
要搜索 flat 对象的值,可以使用 GET 或 POST 请求。即使您不知道字段名称,也可以在整个 flat 对象中搜索叶值。例如,以下请求搜索所有标记为 bug 的问题:
GET /test-index/_search
{
"query": {
"match": {"issue": "bug"}
}
}
或者,如果您知道要搜索的子字段名称,请使用点表示法提供字段的路径:
GET /test-index/_search
{
"query": {
"match": {"issue.labels.category.level": "bug"}
}
}
在这两种情况下,响应都是相同的,并且包含文档 2
:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.0303539,
"hits": [
{
"_index": "test-index",
"_id": "2",
"_score": 1.0303539,
"_source": {
"issue": {
"number": "123457",
"labels": {
"version": "2.2",
"category": {
"type": "API",
"level": "bug"
}
}
}
}
}
]
}
}
使用前缀查询,您可以搜索所有以 2. 开头的版本的问题:
GET /test-index/_search
{
"query": {
"prefix": {"issue.labels.version": "2."}
}
}
使用范围查询,您可以搜索版本 2.0-2.1 的所有问题:
GET /test-index/_search
{
"query": {
"range": {
"issue": {
"gte": "2.0",
"lte": "2.1"
}
}
}
}
将子字段定义为 flat 对象 #
您可以将 JSON 对象的子字段定义为 flat 对象。例如,使用以下查询将 issue.labels
定义为 flattened
:
PUT /test-index/
{
"mappings": {
"properties": {
"issue": {
"properties": {
"number": {
"type": "double"
},
"labels": {
"type": "flattened"
}
}
}
}
}
}
因为 issue.number 不是 flat 对象的一部分,所以您可以使用它来聚合和排序文档。