那么为什么一个叫做正向索引,一个叫做倒排索引呢?
正向索引是最传统的,根据id索引的方式。但根据词条查询时,必须先逐条获取每个文档,然后判断文档中是否包含所需要的词条,是根据文档找词条的过程。
而倒排索引则相反,是先找到用户要搜索的词条,根据词条得到保护词条的文档的id,然后根据id获取文档。是根据词条找文档的过程。
image.png
是不是说,我们学习了elasticsearch就不再需要mysql了呢?
并不是如此,两者各自有自己的擅长支出:

  • Mysql:擅长事务类型操作,可以确保数据的安全和一致性
  • Elasticsearch:擅长海量数据的搜索、分析、计算

因此在企业中,往往是两者结合使用:

  • 对安全性要求较高的写操作,使用mysql实现
  • 对查询性能要求较高的搜索需求,使用elasticsearch实现
  • 两者再基于某种方式,实现数据的同步,保证一致性

    索引库的操作

    按照Rest风格,增删改查分别使用:POST、DELETE、PUT、GET等请求方式,路径一般是资源名称。因此索引库操作的语法类似。

    创建索引库

    创建索引库的请求格式:

  • 请求方式:PUT

  • 请求路径:/索引库名
  • 请求参数:格式:


put /创建的索引库名称
{
“settings”: {
“属性名”: “属性值”
}
}
settings:就是索引库设置,其中可以定义索引库的各种属性,目前我们可以不设置,都走默认。

查询索引库

  • 请求方式:GET
  • 请求路径:/索引库名
  • 请求参数:无

格式:
GET /索引库名
返回的信息也是JSON格式,其中包含这么几个属性:

  • mappings:类型映射,目前我们没有给索引库设置映射
  • settings:索引库配置,目前是默认配置

删除索引库

  • 请求方式:DELETE
  • 请求路径:/索引库名
  • 请求参数:无

格式:

DELETE /索引库名

小结

索引库操作:

  • 创建索引库: PUT /库名称
  • 查询索引库: GET /索引库名称
  • 删除索引库: DELETE /索引库名称

mapping映射属性

映射的属性

mapping是对索引库中文档的约束,常见的mapping属性包括:

  • type:字段数据类型,常见的简单类型有:
    • 字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址)
    • 数值:long、integer、short、byte、double、float、
    • 布尔:boolean
    • 日期:date
    • 对象:object
  • index:是否创建索引,默认为true
  • analyzer:使用哪种分词器
  • properties:该字段的子字段

语法:

PUT /索引库名称
{
“mappings”: {
“properties”: {
“字段名”:{
“type”: “text”,
“analyzer”: “ik_smart”
},
“字段名2”:{
“type”: “keyword”,
“index”: “false”
},
“字段名3”:{
“properties”: {
“子字段”: {
“type”: “keyword”
}
}
},
// …略
}
}
}

索引库已存在

我们假设已经存在一个索引库,此时要给索引库添加映射。

  • 语法

请求方式依然是PUT

PUT /索引库名/_mapping
{
“properties”: {
“字段名1”: {
“type”: “类型”,
“index”: true,
“analyzer”: “分词器”
},
“字段名2”: {
“type”: “类型”,
“index”: true,
“analyzer”: “分词器”
},

}
}

  • 类型名称:就是前面将的type的概念,类似于数据库中的表字段名:任意填写,下面指定许多属性,例如:

    • type:类型,可以是text、long、short、date、integer、object等
    • index:是否参与搜索,默认为true
    • analyzer:分词器
  • 示例

根据下列的json数据设计出索引库heima的映射

{
“title”:”小米手机”,
“images”:”http://image.leyou.com/12479122.jpg“,
“price”:2699.00
}
发起请求:

PUT /heima/_mapping
{
“properties”: {
“title”: {
“type”: “text”,
“analyzer”: “ik_smart”
},
“images”: {
“type”: “keyword”,
“index”: “false”
},
“price”: {
“type”: “float”
}
}
}
响应结果:

{
“acknowledged”: true
}
上述案例中,就给heima这个索引库中设置了3个字段:

  • title:商品标题
    • index:标题一般都参与搜索,所以index没有配置,按照默认为true
    • type: 标题是字符串类型,并且参与搜索和分词,所以用text
    • analyzer:标题内容一般较多,查询时需要分词,所以指定了IK分词器
  • images:商品图片
    • type:图片是字符串,并且url不需要分词,所以用keyword
    • index:图片url不参与搜索,所以给false
  • price:商品价格
    • type:价格,浮点型,这里给了float
    • index:这里没有配置,默认是true,代表参与搜索

并且给这些字段设置了一些属性。

索引库不存在

如果一个索引库是不存在的,我们就不能用上面的语法,而是这样:

PUT /索引库名
{
“mappings”:{
“properties”: {
“字段名1”: {
“type”: “类型”,
“index”: true,
“analyzer”: “分词器”
},
“字段名2”: {
“type”: “类型”,
“index”: true,
“analyzer”: “分词器”
},

}
}
}

  • 示例:

要求:根据下列的json数据设计出索引库heima2的映射

{
“id”: 999,
“title”:”华为手机”,
“images”:”http://image.leyou.com/12479122.jpg“,
“price”:2699.00
}

创建索引库和映射
PUT /heima2
{
“mappings”: {
“properties”: {
“title”: {
“type”: “text”,
“analyzer”: “ik_max_word”
},
“images”: {
“type”: “keyword”,
“index”: “false”
},
“price”: {
“type”: “float”
}
}
}
}

  • 结果:

{
“acknowledged” : true,
“shards_acknowledged” : true,
“index” : “heima2”
}

查看映射关系

查看使用Get请求

  • 语法:

GET /索引库名/_mapping

映射其他操作

对于映射就行修改和删除,ES官方特别声明:
修改:
1.无法修改映射中已有字段进行修改
2.可以向已有的映射中添加映射
删除:
无法直接将索引库下的映射直接删除,只能通过删除索引库来达到删除映射的目的

文档操作

新增文档

新增并随机生成id

通过POST请求,可以向一个已经存在的索引库中添加文档数据。ES中,文档都是以JSON格式提交的。

  • 语法:


POST /{索引库名}/_doc
{
“key”:”value”
}

  • 示例:


# 新增文档数据
POST /heima/_doc
{
“title”:”小米手机”,
“images”:”http://image.leyou.com/12479122.jpg“,
“price”:2699.00
}

  • 响应:


{
“_index” : “heima”,
“_type” : “_doc”,
“_id” : “rGFGbm8BR8Fh6kyTbuq8”,
“_version” : 1,
“result” : “created”,
“_shards” : {
“total” : 2,
“successful” : 1,
“failed” : 0
},
“_seq_no” : 0,
“_primary_term” : 1
}
结果解释:

  • _index:新增到了哪一个索引库。
  • _id:这条文档数据的唯一标示,文档的增删改查都依赖这个id作为唯一标示。此处是由ES随即生成的,我们也可以指定使用某个ID
  • result:执行结果,可以看到结果显示为:created,说明文档创建成功。

新增并指定id

通过POST请求,可以向一个已经存在的索引库中添加文档数据。ES中,文档都是以JSON格式提交的。

  • 语法:


POST /{索引库名}/_doc/{id}
{
“key”:”value”
}

  • 示例:


# 新增文档数据并指定id
POST /heima/_doc/1
{
“title”:”小米手机”,
“images”:”http://image.leyou.com/12479122.jpg“,
“price”:2699.00
}

  • 响应:


{
“_index” : “heima”,
“_type” : “_doc”,
“_id” : “1”,
“_version” : 1,
“result” : “created”,
“_shards” : {
“total” : 2,
“successful” : 1,
“failed” : 0
},
“_seq_no” : 1,
“_primary_term” : 1
}

查询文档

根据rest风格,新增是post,查询应该是get,不过查询一般都需要条件,这里我们把文档id带上。
根据rest风格,新增是post,查询应该是get,不过查询一般都需要条件,这里我们把刚刚生成数据的id带上。
语法:

GET /{索引库名称}/_doc/{id}
通过kibana查看数据:

GET /heima/_doc/rGFGbm8BR8Fh6kyTbuq8
查看结果:
{
“_index”: “heima”, # 索引库
“_type”: “_doc”,
“_id”: “rGFGbm8BR8Fh6kyTbuq8”, # id
“_version”: 1,
“found”: true,
“_source”: { # 查询数据存放在 _source 中
“title”: “小米手机”,
“images”: “http://image.leyou.com/12479122.jpg“,
“price”: 2699
}
}

  • _source:源文档信息,所有的数据都在里面。

删除文档

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

DELETE /{索引库名}/_doc/id值
示例:

根据id删除数据
DELETE /heima/_doc/1

修改文档

修改有两种方式:

  • 全量修改:直接覆盖原来的文档
  • 增量修改:修改文档中的部分字段

    全量修改

    全量修改是覆盖原来的文档,其本质是:

  • 根据指定的id删除文档

  • 新增一个相同id的文档

注意:如果根据id删除时,id不存在,第二步的新增也会执行,也就从修改变成了新增操作了。
语法:

PUT /{索引库名}/_doc/文档id
{
“字段1”: “值1”,
“字段2”: “值2”,
// … 略
}
示例:
要求将文档为2,改为下面的值:

PUT /heima/_doc/2
{
“title”:”大米手机”,
“images”:”http://image.leyou.com/12479122.jpg“,
“price”:2899.00
}

增量修改

增量修改是只修改指定id匹配的文档中的部分字段。
语法:

POST /{索引库名}/_update/文档id
{
“doc”: {
“字段名”: “新的值”,
}
}
示例:
要求:将文件id为1文档的price修改为100元

POST /heima/_update/1
{
“doc”: {
“price”: 100
}
}

总结

文档操作有哪些?

  • 创建文档:POST /{索引库名}/_doc/文档id { json文档 }
  • 查询文档:GET /{索引库名}/_doc/文档id
  • 删除文档:DELETE /{索引库名}/_doc/文档id
  • 修改文档:
    • 全量修改:PUT /{索引库名}/_doc/文档id { json文档 }
    • 增量修改:POST /{索引库名}/_update/文档id { “doc”: {字段}}