elasticsearch 数据类型

  • String 类型
    • text 类型
    • keyword
  • Date 时间类型
  • 复杂类型
  • 地址位置类型
  1. String 类型
    1.1 text 类型-会分词

例如存储:"我爱你嘟嘟"

PUT /china
{
  "mappings": {
    "properties": {
      "word": {
        "type": "text"
      }
    }
  }
}

#插入数据
POST /china/_doc/1
{
  "name": "我爱你嘟嘟"
}

直接搜"我爱你嘟嘟",这句话在ES的倒排序索引中存储的是单个字,所以无法检索。

GET /china/_doc/_search

{
  "query": {
    "term": {
      "name": {
        "value": "我爱你嘟嘟"
      }
    }
  }
}

因为它在es里会分词

GET /_analyze
{
  "text": [
    "我爱你嘟妈妈"
  ],
  "analyzer": "standard"
}

{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "<IDEOGRAPHIC>",
      "position" : 0
    },
    {
      "token" : "爱",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "<IDEOGRAPHIC>",
      "position" : 1
    },
    {
      "token" : "你",
      "start_offset" : 2,
      "end_offset" : 3,
      "type" : "<IDEOGRAPHIC>",
      "position" : 2
    },
    {
      "token" : "嘟",
      "start_offset" : 3,
      "end_offset" : 4,
      "type" : "<IDEOGRAPHIC>",
      "position" : 3
    },
    {
      "token" : "嘟",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "<IDEOGRAPHIC>",
      "position" : 4
    }
  ]
}

1.2 keyword 不会分词

    PUT /china2
    {
      "mappings": {
        "properties": {
          "word": {
            "type": "keyword"
          }
        }
      }
    }

# 这样是可以搜索到的
GET /china2/_doc/_search
{
  "query": {
    "term": {
      "name": {
        "value": "我爱你嘟妈妈"
      }
    }
  }
}

2 Date 类型

PUT /date
{
  "mappings": {
    "properties": {
      "date": {
        "type": "date",
        "format":"见下面"
      }
    }
  }
}

时间格式可以是:日期和时间戳
PUT /date/_doc/1
{ "date": "2015-01-01" }
yyyy-MM-dd

PUT /date/_doc/2
{ "date": "2015-01-01 12:10:30" }
yyyy-MM-dd HH:mm:ss

PUT /date/_doc/3
{ "date": 1420070400001 }
epoch_millis

3 复杂类型

  • Array
  • object
  • nested

    3.1 Array:在Elasticsearch中,数组不需要专用的字段数据类型。默认情况下,任何字段都可以包含零个或多个值,但是,数组中的所有值都必须具有相同的数据类型。

    POST /china/_doc/4
    {
    "name":["这是",2,"不称职","父亲"]
    }

    3.2 object
    object类型的字段,也可以有多个值,形成List<object>的数据结构。List<object>中的object不允许彼此独立地索引查询

#新增字段 filed3 类型是 object
PUT china/_mapping/_doc?include_type_name=true
{
  "properties": {
    "field3": {
      "type": "object"
    }
  }
}

POST /china/_doc/3
{
  "field3":[ { "name":"tohero1", "age":1 }, { "name":"tohero2", "age":2 } ]
}

POST /china/_doc/4
{
  "field3": [ { "name":"tohero1", "age":2 }, { "name":"tohero2", "age":1 } ]
}

#query
GET /china/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "field3.name": "tohero1"
          }
        },
        {
          "term": {
            "field3.age": 1
          }
        }
      ]
    }
  }
}
#结果
"hits" : [
      {
        "_index" : "china",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.1823215,
        "_source" : {
          "field3" : [
            {
              "name" : "tohero1",
              "age" : 1
            },
            {
              "name" : "tohero2",
              "age" : 2
            }
          ]
        }
      },
      {
        "_index" : "china",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 1.1823215,
        "_source" : {
          "field3" : [
            {
              "name" : "tohero1",
              "age" : 2
            },
            {
              "name" : "tohero2",
              "age" : 1
            }
          ]
        }
      }
    ]
  }
}

查到了两条数据:object不允许彼此独立地索引查询。

3.3 nested类型
如果想解决上述问题,就要用nested类型
需要建立对象数组的索引并保持数组中每个对象的独立性,则应使用nested数据类型而不是 object数据类型。在内部,嵌套对象索引阵列作为一个单独的隐藏文档中的每个对象,这意味着每个嵌套的对象可以被独立的查询

```groovy
PUT /mytest
{
"mappings": {
"properties": {
"group": {
"type": "keyword"
},
"user": {
"type": "nested",
"properties": {
"first": {
"type": "keyword"
},
"last": {
"type": "keyword"
},
"age": {
"type": "integer"
}
}
}
}
}
}

PUT /mytest/_doc/1
{
"group": "fans",
"user": {
"first": "Amy",
"last": "White",
"age": 18
}
}

PUT /mytest/_doc/2
{
"group": "fans",
"user": {
"first": "John",
"last": "Smith",
"age": 22
}
}

GET /mytest/_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{
"term": {
"user.first": "Amy"
}
},
{
"term": {
"user.last": "White"
}
}
]
}
}
}
}
}

由于嵌套对象被索引在独立的隐藏文档中,因此我们无法直接使用一般的query去查询他,我们必须改使用 "nested查询" 去查询他们

nestedt查询是一个叶子子句,因此外层需要使用query或是bool来包含它,nested查询是一个叶子子句,所以他也可以像一般的叶子子句一样被bool层层嵌套

nested查询的内部必须要包含一个path参数,负责指定要用的是哪个nested类型的字段,且要包含一个query,负责进行此嵌套对象内的查询

4 GEO 地理位置类型

我想知道从当前位置步行 5 分钟内可到的那些餐馆,对上海更大范围内的其他餐馆并不感兴趣。那么你可能需要知道这种背后的逻辑是怎么执行的?
Elasticsearch 提供了 两种表示地理位置的方式
用纬度-经度表示的坐标点使用 geo_point 字段类型
 以 GeoJSON 格式定义的复杂地理形状,使用 geo_shape 字段类型

Geo-points 允许你找到距离另一个坐标点一定范围内的坐标点、计算出两点之间的距离来排序或进行相关性打分、或者聚合到显示在地图上的一个网格

另一方面,Geo-shapes 纯粹是用来过滤的。它们可以用来判断两个地理形状是否有重合或者某个地理形状是否完全包含了其他地理形状

```groovy
#新建索引
PUT shanghai
{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_point" #类型为geo_point
      }
    }
  }
}
#新建数据
PUT shanghai/_doc/1
{
  "text": "Geo-point as an object",
  "location": { 
    "lat": 41.12,
    "lon": -71.34 #对象形式 lat(纬度) lon(经度)
  }
}

PUT shanghai/_doc/2
{
  "text": "Geo-point as a string",
  "location": "41.12,-71.34" #半角字符串形式 lat,lon
}

PUT shanghai/_doc/3
{
  "text": "Geo-point as a geohash",
  "location": "drm3btev3e86" #hash过后的经纬度
}

PUT shanghai/_doc/4
{
  "text": "Geo-point as an array",
  "location": [ -71.34, 41.12 ] #数组表示 lon,lat
}

#搜索数据:方圆200公里
GET /shanghai/_search
{
    "query": {
        "bool" : {
            "must" : {
                "match_all" : {}
            },
            "filter" : {
                "geo_distance" : { # 找出与指定为在给定距离内的点
                    "distance" : "200km",
                    "location" : {
                        "lat" : 40,
                        "lon" : -70
                    }
                }
            }
        }
    }
}

地理坐标点用
字符串形式表示时是纬度在前,经度在后( "latitude,longitude" ),
而数组形式表示时是经度在前,纬度在后( [longitude,latitude] )—顺序刚好相反
其实,在 Elasticesearch 内部,不管字符串形式还是数组形式,都是经度在前,纬度在后。不过早期为了适配 GeoJSON 的格式规范,调整了数组形式的表示方式。

参考链接:https://blog.csdn.net/weixin_40341116/article/details/80778599

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注