认识Elasticsearch
Elasticsearch是一个开源的分布式搜索和分析引擎,基于Apache Lucene搜索库构建而成。它提供了一个强大的RESTful API,可以用于进行全文搜索、结构化搜索、分析等操作。
Elasticsearch之所以能够实现高性能搜索,主要得益于其底层采用的倒排索引技术。倒排索引是一种数据结构,它将文档中的每个词映射到包含该词的所有文档的列表中,而不是将文档映射到词的列表中。这种结构使得搜索引擎可以快速地定位包含特定词的文档,从而实现高效的搜索。
文档(Document):用来搜索的数据,其中的每一条数据就是一个文档。例如一个网页、一个商品信息等。
词条(Term):对文档数据或用户搜索数据,利用某种算法分词,得到的具备含义的词语就是词条。例如:我是程序员,就可以分为:我、是、程序员、程序这样的几个词条。
那么什么叫正向索引,什么叫倒排索引呢?他们的优缺点是什么?
正向索引:最传统的,根据id索引的方式。但根据词条查询时,必须先逐条获取每个文档,然后判断文档中是否包含所需要的词条,是根据文档找词条的过程。
优点:可以给多个字段创建索引、根据索引字段搜索、排序速度非常快。
缺点:根据非索引字段,或者索引字段中的部分词条查找时,只能全表扫描。
倒排索引:与正向索引相反,倒排索引先找到用户要搜索的词条,根据词条得到保护词条的文档的id,然后根据id获取文档。是根据词条找文档的过程。
优点:根据词条搜索、模糊搜索时,速度非常快。
缺点:只能给词条创建索引而不是字段、无法根据字段做排序。
索引与映射
- 随着业务发展,需要在es中存储的文档也会越来越多,比如有商品的文档、用户的文档、订单文档等。为了方便管理,我们将类型相同的文档集中在一起管理,称为索引(Index)。索引类似于数据库中的表。
- 数据库的表会有约束信息,用来定义表的结构、字段的名称、类型等信息。因此,索引库中就有映射(mapping),是索引中文档的字段约束信息,类似表的结构约束。
我们把mysql与elasticsearch的概念做一下对比:
-
Mysql:正向索引,擅长事务类型操作,可以确保数据的安全和一致性。
-
Elasticsearch:倒排索引,擅长海量数据的搜索、分析、计算。
企业开发中,往往是两者结合使用:
对安全性要求较高的写操作,使用mysql实现
对查询性能要求较高的搜索需求,使用elasticsearch实现
两者再基于某种方式,实现数据的同步,保证一致性
索引库的CRUD
创建索引库:PUT /索引库名
查询索引库:GET /索引库名
删除索引库:DELETE /索引库名
修改索引库,添加字段:PUT /索引库名/_mapping
1、创建索引库和映射
PUT /索引库名称
{
"mappings": {
"properties": {
"字段名":{
"type": "text",
"analyzer": "ik_smart"
},
"字段名2":{
"type": "keyword",
"index": "false"
},
"字段名3":{
"properties": {
"子字段": {
"type": "keyword"
}
}
},
// ...略
}
}
}
2、查询索引库
GET /索引库名
3、修改索引库
PUT /索引库名/_mapping
{
"properties": {
"新字段名":{
"type": "integer"
}
}
}
4、删除索引库
DELETE /索引库名
文档操作
1、新增文档
POST /索引库名/_doc/文档id
{
"字段1": "值1",
"字段2": "值2",
"字段3": {
"子属性1": "值3",
"子属性2": "值4"
},
}
2、查询文档
GET /{索引库名称}/_doc/{id}
3、删除文档
DELETE /{索引库名}/_doc/id值
4、修改文档
(1)全量修改:覆盖原来的文档,其本质是两步操作:
-
根据指定的id删除文档
-
新增一个相同id的文档
注意:如果根据id删除时,id不存在,第二步的新增也会执行,也就从修改变成了新增操作了。
PUT /{索引库名}/_doc/文档id
{
"字段1": "值1",
"字段2": "值2",
// ... 略
}
(2)局部修改:只修改指定id匹配的文档中的部分字段。
POST /{索引库名}/_update/文档id
{
"doc": {
"字段名": "新的值",
}
}
5、批处理
批处理采用POST请求,基本语法如下:
POST _bulk
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_id" : "2" } }
{ "create" : { "_index" : "test", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }