ES 学习笔记(2)

341 阅读4分钟

一、映射字段的基本数据类型

  1. keyword类型

keyword类型是不进行切分,这里的“不进行切分”指的是:在索引时,对keyword类型的数据不进行切分,直接构建倒排索引;在搜索时,对该类型的查询字符串不进行切分后的部分匹配。keyword类型数据一般用于对文档的过滤、排序和聚合。 keyword类型搜索时使用term进行搜索,match搜索不到 2. text类型

text类型是可进行切分的字符串类型。这里的“可切分”指的是:在索引时,可按照相应的切词算法对文本内容进行切分,然后构建倒排索引;在搜索时,对该类型的查询字符串按照用户的切词算法进行切分,然后对切分后的部分匹配打分。 3. 数值类型

ES支持的数值类型有long、integer、short、byte、double、float、half_float、scaled_float和unsigned_long等。为节约存储空间并提升搜索和索引的效率,在实际应用中,在满足需求的情况下应尽可能选择范围小的数据类型。

对于数值型数据,一般使用term搜索或者范围搜索。 4. 布尔类型

布尔类型使用boolean定义,用于业务中的二值表示,如商品是否售罄,房屋是否已租,酒店房间是否满房等。写入或者查询该类型的数据时,其值可以使用true和false,或者使用字符串形式的"true"和"false"。查询是用term。 5. 日期类型

布尔类型使用boolean定义,用于业务中的二值表示,如商品是否售罄,房屋是否已租,酒店房间是否满房等。写入或者查询该类型的数据时,其值可以使用true和false,或者使用字符串形式的"true"和"false"。

一般使用如下形式表示日期类型数据:·格式化的日期字符串。·毫秒级的长整型,表示从1970年1月1日0点到现在的毫秒数。·秒级别的整型,表示从1970年1月1日0点到现在的秒数。日期类型的默认格式为strict_date_optional_time||epoch_millis。其中,strict_date_optional_time的含义是严格的时间类型,支持yyyy-MM-dd、yyyyMMdd、yyyyMMddHHmmss、yyyy-MM-ddTHH:mm:ss、yyyy-MM-ddTHH:mm:ss.SSS和yyyy-MM-ddTHH:mm:ss.SSSZ等格式,epoch_millis的含义是从1970年1月1日0点到现在的毫秒数。

日期类型默认不支持yyyy-MM-dd HH:mm:ss格式,如果经常使用这种格式,可以在索引的mapping中设置日期字段的format属性为自定义格式

PUT /hotel { "mappings":{ "properties":{ "title":{ "type":"text" }, "city":{ "type":"keyword" }, "price":{ "type":"double" }, "create_time":{ //指定日期型字段的格式 "type":"date", "format": "yyyy-MM-dd HH:mm:ss" } } } }

复杂的数据类型

1.数组类型

ES数组没有定义方式,其使用方式是开箱即用的,即无须事先声明,在写入时把数据用中括号[]括起来,由ES对该字段完成定义。

当然,如果事先已经定义了字段类型,在写数据时以数组形式写入,ES也会将该类型转为数组。

  1. 对象类型

和数组类型一样,对象类型也不用事先定义,在写入文档的时候ES会自动识别并转换为对象类型。

    POST /hotel/_doc/001 { //写入数据 "title": "好再来酒店", "city": "青岛", "price": 578.23, "comment_info": { //评论数据 "properties": { "favourable_comment":199, //好评数据 "negative_comment": 68 //差评数据 } } }

3.地理位置 (geo_point)

POST /hotel/_doc/001 { //写入数据 "title": "好再来酒店", "city": "青岛", "price": 578.23, "comment_info": { //评论数据 "properties": { "favourable_comment":199, //好评数据 "negative_comment": 68 //差评数据 } } }
  1. 动态映射 当字段没有定义时,ES可以根据写入的数据自动定义该字段的类型,这种机制叫作动态映射。映射对应类型如下:

image.png 5. 多字段

针对同一个字段,有时需要不同的数据类型,这通常表现在为了不同的目的以不同的方式索引相同的字段。例如,在订单搜索系统中,既希望能够按照用户姓名进行搜索,又希望按照姓氏进行排列,可以在mapping定义中将姓名字段先后定义为text类型和keyword类型,其中,keyword类型的字段叫作子字段,这样ES在建立索引时会将姓名字段建立两份索引,即text类型的索引和keyword类型的索引。订单搜索索引的定义如下:

PUT /hotel_order { "mappings": { "properties": { "order_id": { //定义order_id字段类型为keyword "type": "keyword" }, "user_id": { //定义user_id字段类型为keyword "type": "keyword" }, "user_name": { //定义user_name字段类型为text "type": "text", "fields": { //定义user_name多字段 //定义user_name字段的子字段user_name_keyword,并定义其类型为keyword "user_name_keyword": { "type": "keyword" } } }, "hotel_id": { //定义hotel_id字段类型为keyword "type": "keyword" } } } }

查询

GET /hotel_order/_search { "query": { "match": { //match搜索使用text类型的字段 "user_name": "Jordan" } }, "sort": { //排序使用子字段 "user_name.user_name_keyword": "asc" } }