创建/查看/删除索引库

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

映射属性详解

1type

一级分类

二级分类

具体类型

使用

核心类型

字符串类型

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 
}

响应:

kibana清空索引里的数据 kibana删除索引命令_kibana清空索引里的数据


可以看到结果显示为: created ,应该是创建成功了。另外,需要注意的是,在响应结果中有个 _id 字段,这个就是这条文档数据的 唯一标示 ,以后的增删改


查都依赖这个 id 作为唯一标示。 可以看到id 的值为: PVquG3UBSeWHnsgdVFAg , 这里我们新增时没有指定 id ,所以是 ES 帮我们随机生成的id 。


 


查看文档:


 


GET /lagou/goods/PVquG3UBSeWHnsgdVFAg

kibana清空索引里的数据 kibana删除索引命令_权重_02

  • _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 
}

结果:

kibana清空索引里的数据 kibana删除索引命令_数据_03


可以看到是 created ,是新增。


 


我们再次执行刚才的请求,不过把数据改一下:


kibana清空索引里的数据 kibana删除索引命令_字段_04

可以看到结果是: updated ,显然是更新数据

删除数据:

删除使用DELETE请求,同样,需要根据id进行删除

语法:DELETE /索引库名/类型名/id值

示例:

kibana清空索引里的数据 kibana删除索引命令_权重_05

 


智能判断:


 


刚刚在新增数据时,添加的字段都是提前在类型中定义过的,如果添加的字段并没有提前定义过,能够成功吗?


 


事实上 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 个字段。


 


结果:

kibana清空索引里的数据 kibana删除索引命令_kibana清空索引里的数据_06


在看下索引库的映射关系 :




kibana清空索引里的数据 kibana删除索引命令_权重_07


 


stock 、 saleable 、 subtitle 都被成功映射了。


 


subtitle 是 String 类型数据, ES 无法智能判断,它就会存入两个字段。例如:


  • subtitle:text类型
  • subtitle.keyword:keyword类型

这种智能映射,底层原理是动态模板映射,如果我们想修改这种智能映射的规则,其实只要修改动态模板即可!


 


动态映射模板


 


语法:



kibana清空索引里的数据 kibana删除索引命令_权重_08


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并存,说明我们的动态模板生效了!