搜索引擎Elasticsearch
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。
核心术语
ES就相当于一个数据库
索引index在最新版本可以理解为一个表(为什么说是最新版本呢,因为在老版本在index下还有一个type的概念,但现在被移除了。所以现在index可以直接定型为一个表的概念)
文档docunment可以理解为一行记录
字段fields可以理解为一列
在使用过程中,其结果以json格式返回,如下:
stu_index //docunment,表名
{
id: 1001,
name: jason,
age: 19
},
{
id: 1002,
name: tom,
age: 18
},
{
id: 1003,
name: rose,
age: 22
}
-
集群相关
分片(shard) 这个就类似于hdfs中的数据块,为了提高查询的吞吐量,将一个完整文档的数据切分成多个数据块并可能存储在不同的地方,这个样在查询的时候可以并行地在多个shard上进行查询
副本(replicas) 因为数据块的分布式存储,导致了任意数据块出现异常的可能性增加,为了提高容错性会为每个shard产生1或者N个副本,那么即使主副本丢失了,备用副本也能继续使用 -
简称
主副本(shard)
备用副本(replicas)
倒排索引
在介绍倒排索引前,我们先从正排索引上入手
在我们使用数据库的时候,总是会为每条记录定义一个id(主键),这样在搜索的时候由主键去搜索是最快的,HBase就是严格执行这个原理,所以其在数千万量级的随机读取还是很快的。
但是,如果要对其内容进行检索的时候,我们没办法提前知道我们要搜索的内容的id(主键)是什么并且我们都是对其某些字段进行模糊匹配的。这个时候正排索引就没什么用,而使用SQL中模糊匹配对一般数据的性能又产生了极大的损耗。
所以,现在所有的搜索引擎都是基于倒排索引的。那倒排索引又是如何工作的?
- 首先是基于分词,将表中可以用来检索的字段中的内容进行分词
- 由于一个词是可以出现在任意的记录下,所以为这个分词后得到的词建立它所在记录的主键id之间的对应关系,这就有点像2级索引了。
- 当搜索到要检索的词后,根据其对应的主键id来提取相应的记录
安装及部署
1.在官网上下载es的安装tar包(一般建议部署在Linux系统上),上传到服务器上
2.创建一个es专有的用户,因为es是不可以用root用户来启动的
3.解压到指定的目录下,这里自己决定就好了
4.进入es的目录中,到config目录中,修改elasticsearch.yml配置文件,修改内容如下:
cluster.name: doudou-cluster # 这里是定义你的集群名称,自由发挥吧
node.name: es-node1 # 当前节点的名称
path.data: ${ELASTICSEARCH_HOME}/data # 这里需要你在es的目录下创建一个data目录,用于数据存储
path.logs: ${ELASTICSEARCH_HOME}/logs # 这个目录是本来就有的
network.host: 0.0.0.0 # 表示任意机器都能连接到我们的es集群
http.port: 9200 # 这个是es的通讯端口,改不改都可以
cluster.initial_master_nodes: ["es-node1'] # 这里填你要连接机器的名称,就是上面node.name中定义的
# 退出保存
再进入到jvm.options这个配置目录上
# -Xms1g
# -Xmx1g
# 这里主要看你机器的配置了,如果是公司生产环境的可以直接使用1g甚至更多的
-Xms128m
-Xmx123m
这个时候使用你创建的es用户来启动(其实,刚才上面的上传解压配置最好都是用es用户来执行,这样所有文件权限都一致,不用再改es目录下文件或者目录的权限),会报错:
我们还需要修改一下centos7系统的配置文件
vim /etc/security/limits.conf
# 添加如下内容,如果有相应的直接注掉就可以了
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096
# 退出
另外一个配置文件
vi /etc/sysctl.conf
# 添加如下内容
vm.max_map_count=262145
然后,可以启动elasticsearch。进入到es的bin目录下,输入
./elasticsearch -d # 后台启动
以上都是基于centos7进行安装
配置Header对es进行可视化操作
网址:github.com/mobz/elasticsearch-header
有两种方法可以
- 使用科学上网在chorme上安装一个插件Elasticsearch Head
- 下载node.js来安装,其实编译过程使用科学上网会快很多
git clone git://github.com/mobz/elasticsearch-head.git
cd elasticsearch-head
npm install
npm run start
# 在浏览器上输入就http://localhost:9100/ 然后连接到你的es服务器就可以了
基本操作
获取集群健康状态
GET /_cluster/health
查看es现有的索引
GET _cat/indices?v
删除索引
DELETE /index_test # 这里的index_test为一个索引的名称
索引的mappings映射,可以理解为是表的schema信息
其中如果某个字段上的属性index为true的话,意味着可以被索引(默认为true)
创建索引的同时创建mappings(仅仅是定义mappings)
# 创建一个索引要使用PUT方法 路游为索引名称
PUT /index_str
{
"mappings": { # 创建时要加上这个属性
"properties": { # properties为字段的统称,固定写法
"realname": {
"type": "text", # 字段类型
"index": true # 定义是否能索引,一般默认为true
},
"username": {
"type": "keyword",
"index": false
}
}
}
}
当创建完索引和其mappings后,可以查看你所创建的字段的分词效果
GET /index_mapping/_analyze # 在索引名称后面添加一个_analyze的路游名称
{
"field": "realname",
"text": "imooc is good"
}
修改索引的mappings,但是设置好的属性是不能添加的,你只能增加索引的字段属性
如果索引已创建,要添加一个mappings上去,方法和修改一样
POST /index_str/_mapping # 修改时需要加上_mapping这个路游
{ # 不再需要"mappings"这个属性名称了
"properties": {
"name": {
"type": "long"
}
}
}
重要的数据类型
text, keyword, string
long, integer, short, byte
double, float
boolean
date
object
数组不能混,类型一致
在新版本上string类型已经不存在了,使用text这个类一般是用在一个长文本之上的,可以被分词。
而keyword类型一般用在关键字上,不能被分词
添加文档
因为索引已经存在所以添加文档时和修改索引一样使用POST方法
POST /my_doc/_doc/1
# {索引名}/_doc/{索引ID}(是指索引在es中的id,而不是这条记录的id,比如记录的id从数据库来是1001,并不是这个。如果不写,则自动生成一个字符串。建议和数据id保持一致> )
# 这里_doc路游是固定写法了,_doc/1这里的这个1是自定上es的记录主键,也可以不加那么es将自动为你分配
{ # 下面这些id,name,desc,create_date都是属性字段
"id": 1001,
"name": "imooc-1",
"desc": "imooc is very good",
"create_date": "2019-12-24"
}
删除文档
DELETE /my_doc/_doc/1 # 只需要指定索引名称和主键就可以了,但是还是要添加_doc这个路游
修改文档,部分修改(如修改某个字段)
POST /my_doc/_doc/1/_update
{
"doc": {
"name": "慕课"
}
}
全文替换,就是把完整的一条记录的数据改掉和创建一样
PUT /my_doc/_doc/1
{
"id": 1002,
"name": "imooc-2",
"desc": "yes yes yes !",
"create_date": "2020-3-18"
}
无论是删除还是修改,每次操作version都会增加,而且删除也不是物理删除而是逻辑删除,无论多少次删除都能看到version在增加
查询文档
GET /my_doc/_doc/1 # 指定查找一个主键的记录
GET /mu_doc/_doc/_search # 全量的就加一个路由_search
反馈结果
{
"_index": "my_doc",
"_type": "_doc",
"_id": "2",
"_score": 1.0,
"_version": 9,
"_source": {
"id": 1002,
"name": "imooc-2",
"desc": "imooc is fashion",
"create_date": "2019-12-25"
}
}
上面除了_source外都是一些元数据
获取指定字段
GET /index_demo/_doc/1?_source=id,name
GET /index_demo/_doc/_search?_source=id,name
判断文档是否存在,看状态码是否是200
HEAD /index_demo/_doc/1
指定分词器
POST /_analyze
{
"analyzer": "standard",
"text": "text文本"
}
POST /my_doc/_analyze
{
"analyzer": "standard",
"field": "name",
"text": "text文本"
}
es内置分词器
- standard:默认分词,单词会被拆分,大小会转换为小写。
- simple:按照非字母分词。大写转为小写。
- whitespace:按照空格分词。忽略大小写。
- stop:去除无意义单词,比如the/a/an/is…
- keyword:不做分词。把整个文本作为一个单独的关键词。
IK分词器
Github:https://github.com/medcl/elasticsearch-analysis-ik
下载zip包后,解压到es的plugins这个目录下
自定义中文词库
在plugins目录下找到ik的文件夹,cd过去,里面的config目录下修改IKAnalyzer.cfg.xml文件
<entry key="ext_dict">custom.dic</entry>
# 这个custom.dic为和IKAnalyzer.cfg.xml的同级文件,自行创建
vim custom.dic
# 一行一个词
中文
英文
然后退出编辑模式保存重启es就可以了