创建/查看/删除索引库
PUT /goods # 添加索引
GET /goods # 查看索引
HEAD goods # 查看索引是否存在
DELETE /goods # 删除索引
创建字段映射
PUT /索引库名/_mapping/typeName
{
"properties":{
"字段名":{
"type": "类型",
"index": true,
"store": true,
"analyzer": "分词器"
}
}
}
- 类型名称:就是前面将的type的概念,类似于数据库中的表字段名:任意填写,下面指定许多属性,例如:
- type:类型,可以是text、keyword、long、short、date、integer、object等
- index:是否索引,默认为true
- store:是否存储,默认为false
- analyzer:分词器,这里的 ik_max_word 即使用ik分词器
查看映射关系
GET /索引库名/_mapping
映射属性详解
1)type
一级分类 | 二级分类 | 具体类型 | 使用 |
核心类型 | 字符串类型 | text,keyword | 结构化搜索,全文文本搜索、聚合、排序等 |
整数类型 | integer,long,short,byte | 字段的长度越短,索引和搜索的效率越 高。 | |
浮点类型 | double,float,half_float,scaled_float | | |
逻辑类型 | boolean | | |
日期类型 | date | | |
范围类型 | range | | |
二进制类型 | binary | 该 binary 类型接受二进制值作为 Base64 编码的字符串。该字段默认情况下不存储(store) ,并且不可搜索 | |
复合类型 | 数组 类型 | array | |
对象类型 | object | 用于单个 JSON 对象 | |
嵌套类型 | nested | 用于 JSON 对象数组 | |
地理类型 | 地理坐标类型 | geo_point | 纬度 / 经度积分 |
地理地图 | geo_shape | 用于多边形等复杂形状 | |
特殊类型 | IP 类型 | ip | 用于 IPv4 和 IPv6 地址 |
范围类型 | completion | 提供自动完成建议 | |
令牌计数类型 | token_count | 计算字符串中令牌的数量 |
说几个关键的:
- String类型,又分两种:
- text:使用文本数据类型的字段,它们会被分词,文本字段不用于排序,很少用于聚合,如文章标题、正文。
- keyword:关键字数据类型,用于索引结构化内容的字段,不会被分词,必须完整匹配的内容,如邮箱,身份证号。支持聚合
- 这两种类型都是比较常用的,但有的时候,对于一个字符串字段,我们可能希望他两种都支持,此时,可以利用其多字段特性
"properties": {
"title":{
"type": "text",
"analyzer": "ik_max_word",
"fields": {
"sort":{
"type": "keyword"
}
},
"index": true
}
}
- Numerical:数值类型,分两类
- 基本数据类型:long、interger、short、byte、double、float、half_float
- double 双精度64位
- float 单精度32位
- half_float 半精度16位
- 浮点数的高精度类型:scaled_float
- 带有缩放因子的缩放类型浮点数,依靠一个 long 数字类型通过一个固定的( double 类型)缩放因数进行缩放.
- 需要指定一个精度因子,比如10或100。elasticsearch会把真实值乘以这个因子后存储,取出时再还原。
- Date:日期类型
- elasticsearch可以对日期格式化为字符串存储,但是建议我们存储为毫秒值,存储为long,节省空间。
- Array:数组类型
- 进行匹配时,任意一个元素满足,都认为满足
- 排序时,如果升序则用数组中的最小值来排序,如果降序则用数组中的最大值来排序
- 字符串数组:["one", "two"]
- 整数数组:[1,2]
- 数组的数组:[1, [2, 3]],等价于[1,2,3]
- 对象数组:[ { "name": "Mary", "age": 12 }, { "name": "John", "age": 10 }]
2 ) index
- index影响字段的索引情况。
- true:字段会被索引,则可以用来进行搜索过滤。默认值就是true,只有当某一个字段的index值设置为true时,检索ES才可以作为条件去检索。
- false:字段不会被索引,不能用来搜索
index的默认值就是true,也就是说你不进行任何配置,所有字段都会被索引。
但是有些字段是我们不希望被索引的,比如商品的图片信息(URL),就需要手动设置index为false。
3 ) store
是否将数据进行 额外 存储。
在学习 lucene 时,我们知道如果一个字段的 store 设置为 false ,那么在文档列表中就不会有这个字段的值,用户的搜索结果中不会显示出来。
但是在 Elasticsearch 中,即便 store 设置为 false ,也可以搜索到结果。
原因是 Elasticsearch 在创建文档索引时,会将文档中的原始数据备份,保存到一个叫做 _source 的属性中。而且我们可以通过过滤 _source 来选择哪些要显示,哪些不显示。
而如果设置 store 为 true ,就会在 _source 以外额外存储一份数据,多余,因此一般我们都会将 store 设置为false ,事实上, store 的默认值就是 false 。
在某些情况下,这对 store 某个领域可能是有意义的。例如,如果您的文档包含一个 title ,一个date 和一个非常大的 content 字段,则可能只想检索 the title 和 the date 而不必从一个大 _source字段中提取这些字段:
PUT my_index
{
"mappings": {
"_doc": {
"properties": {
"title": {
"type": "text",
"store": true
},
"date": {
"type": "date",
"store": true
},
"content": {
"type": "text"
}
}
}
}
}
4 ) boost
网站权重:网站权重是指搜索引擎给网站(包括网页)赋予一定的权威值,对网站(含网页)权威的评估评价。一个网站权重越高,在搜索引擎所占的份量越大,在搜索引擎排名就越好。提高网站权重,不但利于网站(包括网页)在搜索引擎的排名更靠前,还能提高整站的流量,提高网站信任度。所以提高网站的权重具有相当重要的意义。 权重即网站在SEO中的重要性,权威性。英文:Page Strength。1、权重不等于排名 2、权重对排名有着非常大的影响 3、整站权重的提高有利于内页的排名。
权重,新增数据时,可以指定该数据的权重,权重越高,得分越高,排名越靠前。
PUT my_index
{
"mappings": {
"_doc": {
"properties": {
"title": {
"type": "text",
"boost": 2
},
"content": {
"type": "text"
}
}
}
}
}
title 字段上的匹配项的权重是字段上的匹配项的权重的两倍 content ,默认 boost 值为 1.0 。提升仅适用于 Term 查询(不 提升 prefix , range 和模糊查询)。
一次创建索引库和类型
put /索引库名
{
"settings":{
"索引库属性名":"索引库属性值"
},
"mappings":{
"类型名":{
"properties":{
"字段名":{
"映射属性名":"映射属性值"
}
}
}
}
}
例如:
PUT /lagou2 {
"settings": {},
"mappings": {
"goods": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
}
kibana对文档操作
新增并随机生成id:
语法:
POST /索引库名/类型名
{
"key":"value"
}
示例:
POST /lagou/goods/
{
"title":"小米手机",
"images":"http://image.lagou.com/12479122.jpg",
"price":2699.00
}
响应:
可以看到结果显示为: created ,应该是创建成功了。另外,需要注意的是,在响应结果中有个 _id 字段,这个就是这条文档数据的 唯一标示 ,以后的增删改
查都依赖这个 id 作为唯一标示。 可以看到id 的值为: PVquG3UBSeWHnsgdVFAg , 这里我们新增时没有指定 id ,所以是 ES 帮我们随机生成的id 。
查看文档:
GET /lagou/goods/PVquG3UBSeWHnsgdVFAg
- _source :源文档信息,所有的数据都在里面。
- _id :这条文档的唯一标示
- 自动生成的id,长度为20个字符,URL安全,base64编码,GUID(全局唯一标识符),分布式系统并行生成时不可能会发生冲突
- 在实际开发中不建议使用ES生成的ID,太长且为字符串类型,检索时效率低。建议:将数据表中唯一的ID,作为ES的文档ID
新增文档并自定义id :
如果我们想要自己新增的时候指定 id ,可以这么做:
语法:
POST /索引库名/类型/id值
{ ... }
示例:
POST /lagou/goods/2
{
"title":"大米手机",
"images":"http://image.lagou.com/12479122.jpg",
"price":2899.00
}
修改数据:
- PUT:修改文档
- POST:新增文档
- 把刚才新增的请求方式改为PUT,就是修改了。不过修改必须指定id,
- id对应文档存在,则修改
- id对应文档不存在,则新增
比如,我们把使用 id 为 3 ,不存在,则应该是新增:
PUT /lagou/goods/3
{
"title":"超米手机",
"images":"http://image.lagou.com/12479122.jpg",
"price":3899.00,
"stock": 100,
"saleable":true
}
结果:
可以看到是 created ,是新增。
我们再次执行刚才的请求,不过把数据改一下:
可以看到结果是: updated ,显然是更新数据
删除数据:
删除使用DELETE请求,同样,需要根据id进行删除
语法:DELETE /索引库名/类型名/id值
示例:
智能判断:
刚刚在新增数据时,添加的字段都是提前在类型中定义过的,如果添加的字段并没有提前定义过,能够成功吗?
事实上 Elasticsearch 非常智能,你不需要给索引库设置任何 mapping 映射,它也可以根据你输入的数据来判断类型,动态添加数据映射。
测试一下:
PUT /lagou/goods/3
{
"title":"超米手机",
"images":"http://image.lagou.com/12479122.jpg",
"price":3899.00,
"stock": 200,
"saleable":true,
"subTitle":"大米"
}
我们额外添加了 stock 库存, saleable 是否上架, subtitle 副标题、 3 个字段。
结果:
在看下索引库的映射关系 :
stock 、 saleable 、 subtitle 都被成功映射了。
subtitle 是 String 类型数据, ES 无法智能判断,它就会存入两个字段。例如:
- subtitle:text类型
- subtitle.keyword:keyword类型
这种智能映射,底层原理是动态模板映射,如果我们想修改这种智能映射的规则,其实只要修改动态模板即可!
动态映射模板 :
语法:
1 )模板名称,随便起
2 )匹配条件,凡是符合条件的未定义字段,都会按照这个规则来映射
3 )映射规则,匹配成功后的映射规则
举例,我们可以把所有未映射的 string 类型数据自动映射为 keyword 类型:
PUT lagou3
{
"mappings": {
"goods": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
}
},
"dynamic_templates": [
{
"strings": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword",
"index":false,
"store":true
}
}
}
]
}
}
}
在这个案例中,我们把做了两个映射配置:
- title字段:统一映射为text类型,并制定分词器
- 其它字段:只要是string类型,统一都处理为keyword类型。
这样,未知的 string 类型数据就不会被映射为 text 和 keyword 并存,而是统一以 keyword 来处理! 我们试试看新增一个数据:
POST /lagou3/goods/1
{
"title":"超大米手机",
"images":"http://image.lagou.com/12479122.jpg",
"price":3299.00
}
我们只对 title 做了配置,现在来看看 images 和 price 会被映射为什么类型呢:
GET /lagou3/_mapping
结果:
{
"lagou3": {
"mappings": {
"goods": {
"dynamic_templates": [
{
"strings": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
}
],
"properties": {
"images": {
"type": "keyword"
},
"price": {
"type": "float"
},
"title": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
}
}
可以看到 images 被映射成了 keyword ,而非之前的 text 和 keyword并存,说明我们的动态模板生效了!