ES索引字段类型详情_7_3

binary类型

binary类型存储字符串base64处理之后的值

date类型

json格式没有date类型,ES中表示date类型的有以下三种:
1)、字符串格式,如’2020-01-01’或’2020/05/26 09:45:00’;
2)、long类型数值,表示从毫秒开始的计数;
3)、integer类型数值,表示从秒开始的计数;

内部date会转换成UTC时间并以毫秒表示其值;
日期查询会在内部转换为long类型形式的范围查询,并且聚合和存储字段的结果将转换为字符串(具体取决于该字段的日期转换格式);
日期将始终以字符串形式呈现,即使一开始在JSON文档中提供的类型为long;

//date类型字段定义
PUT /date_index_demo
{
  "mappings": {
    "properties": {
      "date":{
        "type": "date"
      }
    }
  }
}

PUT /date_index_demo/_doc/1
{
  "date":"2020-01-01"
}

PUT /date_index_demo/_doc/2
{
  "date":"2020-01-01T12:00:00Z"
}

PUT /date_index_demo/_doc/3
{
  "date":"2020-01-01T12:00:00"
}

PUT /date_index_demo/_doc/4
{
  "date":1420070400001
}

//排序查询,内部会转为long类型进行处理
GET /date_index_demo/_search
{
  "sort": [
    {
      "date": {
        "order": "asc"
      }
    }
  ]
}

日期的多种格式化形式
可以使用||分隔符指定多种日期格式,es会依次尝试每种格式,直到找到匹配的格式,将日期格式转换成字符串会优先使用第一种格式转化;

PUT /date_index_demo
{
  "mappings": {
    "properties": {
      "date":{
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss || yyyy-MM-dd || epoch_millis"
      }
    }
  }
}

join类型

存在的约束:
1)、一个索引当中仅允许一个join类型的映射;
2)、父文档与子文档一定要在同一个分片之上,这就意味着在做get/delete/update操作的时候需要指定相同的routing值;
3)、一个元素可以有多个子级,只允许有一个父级;
4)、允许在join类型的字段上添加一个新的关系;
5)、允许在一个元素中添加一个子级(要求元素需要存在父级);

使用父级join查询

父级join查询及聚合操作
参考has_child和has_parent查询,children聚合及inner hits;
join标识字段可以使用聚合和脚本查询,也可以使用parent_id查询;

同一父级对应多个子级

keyword类型

针对类似于ID、邮箱、域名、状态、邮政编码和标签之类的表示字段,在查询操作时以精确值作为条件,同时可作为排序和聚合操作;
如果针对文本内容做全文索引,使用text字段表示更合适;
数值数据不一定需要用数值类型来表示,若不用于range查询则可以使用keyword代替,因为keyword类型字段针对term或term-level的查询更加友好;
考虑将字段设置成keyword类型可考虑以下因素:
1)、针对该字段有没有range操作的需求;
2)、查询效率上的考虑,因为字段类型为keyword相比数值类型效率更高;

nested类型

nested类型是object类型的一种特殊形式,其允许对象数组被索引且可以独立进行查询;
es没有内部对象的概念,因此其将对象继承结构转成简单的key-value的list结构;

PUT /nested_type_index/_doc/1
{
  "group": "fans",
  "user": [
    {
      "first": "John",
      "last": "Smith"
    },
    {
      "first": "Alice",
      "last": "White"
    }
  ]
}

自动映射会自动将user添加为object类型,内部会将文档转成以下格式:

{
  "group" : "fans",
  "user.first" : [ "alice", "john" ],
  "user.last" :  [ "smith", "white" ]
}

这种情况下会将user.first和user.last转化成多值字段,这样会导致alice与white之间的关联关系丢失,从而造成查询时结果的不准确:

GET /nested_type_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "user.first": "Alice"
          }
        },
        {
          "match": {
            "user.last": "Smith"
          }
        }
      ]
    }
  }
}

使用nested字段表示对象数组
可以表示对象数组同时能够保证数组中的对象相互独立,内部将数组中对象看做不同的doc,这就表示可以针对这些对象可使用nested query进行独立查询;

PUT /nested_type_index_1
{
  "mappings": {
    "properties": {
      "user":{
        "type": "nested"
      }
    }
  }
}

PUT /nested_type_index_1/_doc/1
{
  "group": "fans",
  "user": [
    {
      "first": "John",
      "last": "Smith"
    },
    {
      "first": "Alice",
      "last": "White"
    }
  ]
}
//查看映射字段类型
GET /nested_type_index_1/_mapping
//
GET /nested_type_index_1/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "user.first": "Alice"
          }
        },
        {
          "match": {
            "user.last": "Smith"
          }
        }
      ]
    }
  }
}

GET /nested_type_index_1/_search
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "user.first": "Alice"
              }
            },
            {
              "match": {
                "user.last": "White"
              }
            }
          ]
        }
      },
      "inner_hits": {
        "highlight": {
          "fields": {
            "user.first": {}
          }
        }
      }
    }
  }
}

文档字段类型为nested的可行操作:
1)、使用nested查询;
2)、使用nested和reverse_nested聚合查询;
3)、使用nested sorting进行排序;
4)、使用nested inner hits进行检索或高亮匹配;

nested类型映射及对象的限制
因为nested对象在Lucene中是以单独的文档进行索引的,故而若一个索引结构中存在nested类型字段且索引时nested类型字段对应有100个,这时Lucene会创建101个doc;因为nested类型关联代价比较大,es提供以下配置解决性能问题:

序号 参数 说明
1 index.mapping.nested_fields.limit 限制nested类型字段数量
2 index.mapping.nested_objects.limit 限制nested类型字段可包含的对象数量

numeric类型

序号 类型 范围
1 long -2^63 ~ 2^63-1
2 integer -2^31 ~ 2^31-1
3 short -32768 ~ 32767
4 byte -128 ~ 127
5 double 64位精度
6 float 32位精度
7 half_float 16位精度
8 scaled_float 可配置scaling_factor参数
PUT numeric_type_index
{
  "mappings": {
    "properties": {
      "number_of_bytes": {
        "type": "integer"
      },
      "time_in_seconds": {
        "type": "float"
      },
      "price": {
        "type": "scaled_float",
        "scaling_factor": 100
      }
    }
  }
}

range类型

range类型细分有:integer_range、float_rangellong_range、double_range、date_range、ip_range

//索引定义
PUT range_type_index
{
  "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_type_index/_doc/1
{
  "expected_attendees":{
    "gte":10,
    "lte":20
  },
  "time_frame":{
    "gte":"2020-05-28 12:00:00",
    "lte":"2020-07-01"
  }
}

GET /range_type_index/_search
{
  "query": {
    "term": {
      "expected_attendees": {
        "value": 20
      }
    }
  }
}

GET /range_type_index/_search
{
  "query": {
    "range": {
      "time_frame": {
        "gte": "2020-05-29",
        "lte": "2020-06-01",
        "relation":"contains"
      }
    }
  }
}

text类型

适用于全文索引,text类型的字段会首先被分词器解析成一个个词元(term),然后才被索引;若一个字段既想作为text类型又想作为keyword类型,可以使用多字段映射进行处理;

token count类型

PUT token_count_type_index
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "fields": {
          "length": {
            "type": "token_count",
            "analyzer": "standard"
          }
        }
      }
    }
  }
}

PUT token_count_type_index/_doc/1
{
  "name":"John Smith"
}

PUT token_count_type_index/_doc/2
{
  "name":"Rachel Alice Williams"
}

GET token_count_type_index/_search
{
  "query": {
    "term": {
      "name.length": {
        "value": 3
      }
    }
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章