术语名 | 英文名 | 解释 |
---|---|---|
索引 | index | 相当于数据库的表 |
类型 | type | 相当于表的逻辑类型(新版本中已经不再使用) |
文档 | document | 相当于行,一条数据 |
字段 | fields | 相当于列,一个属性 |
概念名 | 英文名 | 解释 |
---|---|---|
映射 | mapping | 表结构定义 |
近实时 | NRT(Near real time) | 当创建文档或者索引的时候 并不是完全实时的,会有一个1秒左右的延迟,所以叫近实时 |
节点 | node | 每一个服务器都是一个节点 |
数据分片 | shard | 把索引库拆分为多份,分别放在不同的节点上,比如有3个节点,3个节点的所有数据内容加在一起是一个完整的索引库。分别保存到三个节点上,目的为了水平扩展,提高吞吐量。 |
备份 | replica | 每个shard的备份,当节点上的主分片(shard)挂掉之后,replica会负责容错,以及承担读请求负载(replica不应当和shard放在同一个服务器上,否则节点宕机,shard和replica都丢失,起不到容错的作用) |
了解倒排索引之前先要了解正排索引,如下:
文档id | 文档内容 |
---|---|
1 | QQ是常用的聊天软件 |
2 | 用QQ进行聊天 |
3 | 常用的聊天软件有QQ |
正排索引就是通过索引id可以找到对应的内容,倒排就是相反的通过内容的片段可以找到对应的索引,然后再找到文件内容,如下:
单词 | 文档ids | 词频TF:位置POS (下面的格式的意思是 id:出现的次数:<单词在文档中出现的位置索引>) |
---|---|---|
1,2,3 | 1:1:<1>,2:1:<2>,3:1<8> | |
常用的 | 1,2 | (下面不再举例了)… |
聊天 | 1,2,3 | … |
软件 | 1,3 | … |
聊天软件 | 1,3 | … |
进行 | 2 | … |
用 | 1,2,3 | … |
有 | 3 | … |
在搜索引擎中每个文件都对应一个文件ID,文件内容被表示为一系列关键词的集合(实际上在搜索引擎索引库中,关键词也已经转换为关键词ID)。例如上面的例子经过分词,提取了8个关键词,每个关键词都会记录它在文档中的出现次数和出现位置。
倒排索引源于实际应用中需要根据属性的值来查找记录。这种索引表的每一项,都包括一个属性值和包含该属性值的各个记录地址。由于不是根据记录来确定属性,而是根据属性来确认记录的位置,所以称之为倒排索引。
https://www.elastic.co/cn/downloads/elasticsearch
#解压到/usr/local/目录下
tar -zxvf elasticsearch-7.4.2-linux-x86_64.tar.gz -C /usr/local/
#进入解压的目录
cd /usr/local/elasticsearch-7.4.2
#添加l两个文件夹 用于以后做数据和日志存放目录
mkdir data
mkdir logs
核心配置是es根目录下config文件夹里的elasticsearch.yml
#打开核心配置文件
vim elasticsearch.yml
#集群名称,单节点也是可以定义
cluster.name: keyboard-dog-elasticsearch
#节点名称
node.name: es-node1
#数据存放路径
path.data: /usr/local/elasticsearch-7.4.2/data
#日志存放路径
path.logs: /usr/local/elasticsearch-7.4.2/logs
#绑定可以操作的地址 0.0.0.0表示所有的ip地址都可以访问操作
network.host: 0.0.0.0
#用于访问的端口
http.port: 9200
#添加跨域配置
http.cors.enabled: true
#可以跨域的地址
http.cors.allow-origin: "*"
#设置一系列符合主节点条件的节点的主机名或 IP 地址来引导启动集群
#这里的es-node1是在上面配置过了
cluster.initial_master_nodes: ["es-node1"]
JVM配置是es根目录下config文件夹里的jvm.options
#打开核心配置文件
vim jvm.options
#在虚拟机或者自己学习的时候把jvm的初始化和最大堆空间修改小一点
#生成环境可以根据机器配置适量增大或减少
-Xms128m
-Xmx128m
ES默认是禁止root用户启动的,所以需要添加一个用户
#添加一个名叫esuser系统用户
useradd esuser
#进行授权
chown -R esuser:esuser /usr/local/elasticsearch-7.4.2
#切换到esuser用户
su esuser
#进入bin目录
cd bin
#启动ES
./elasticsearch
启动的时候会返现出现错误
ERROR: [3]bootstrap checks failed
[1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65535]
[2]: max number of threds [3756] for user [esuser] is too low, increase to at least[4096]
[3]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
第一个问题的意思是:ES能打开的文件数量太少了 要提升
第二个问题的意思是:esuser能使用的最大线程数太少了,也需要提升
第三个问题的意思是:虚拟内存的最大值太低了
这些问题主要是系统配置上的问题,需要修改系统配置文件
#切换到root用户
su root
#修改系统安全限制配置文件
vim /etc/security/limits.conf
翻到文件最下方,添加如下内容
#soft代表警告的设定,可以超过这个设定值,但是超过后会有警告
#hard代表严格的设定,不允许超过这个设定的值
#nofile是每个进程可以打开的文件数的限制
#nproc是操作系统级别对每个用户创建的进程数的限制
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096
保存并退出,再修改系统控制配置
#修改系统控制配置
vim /etc/sysctl.conf
在文件最下方添加配置
vm.max_map_count=262145
保存并退出,然后刷新配置文件
sysctl -p
切换回esuser用户
su esuser
切换到ES的bin目录启动ES
#前台启动的方式
./elasticsearch
#后台启动的方式
./elasticsearch -d
通过访问ip:9200可以查看es的相关配置
端口号意义
https://chrome.google.com/webstore/category/extensions?hl=zh-CN
git clone git://github.com/mobz/elasticsearch-head.git
node -v
npm -v
打开cmd并进入ES–head的源码目录
npm install
npm run start
在ES的核心配置文件里面添加跨域配置
上面已经设置过了,如果你无法连接,回头再看一下
设置之后记得重启一下ES
http://localhost:9100/
主要数据类型
在Elasticsearch中,数组不需要一个特定的数据类型,任何字段都默认可以包含一个或多个值,当然,这多个值都必须是字段指定的数据类型
text:文字类需要被分词被倒排索引的内容,比如商品名称,商品详情,商品介绍,使用text。
keyword:不会被分词,不会被倒排索引,直接匹配搜索,比如订单状态,用户qq,微信号,手机号等,这些精确匹配,无需分词。
1)打开es-head
2)点击table页的索引栏
3)点击新建索引
这里我们把分片数设置5,占时不需要副本,副本数设置为0,索引名随意,我设置为index_demo
使用put请求访问 ip:9200/索引名
在body中添加分片数和副本数信息
{
"setting": {
"index": {
"number_of_shards": "2",
"number_of_replicas": "0"
}
}
}
创建的同时定义字段类型(mappings自定义映射)
{
"mappings": {
"properties": {
"realname": {
"type": "text",
"index": true
},
"username": {
"type": "keyword",
"index": flase
}
}
}
"setting": {
"index": {
"number_of_shards": "2",
"number_of_replicas": "0"
}
}
}
1)刷新一下页面,进入概览
可以看到新建索引的情况,有从0到4五个分片,都是绿色的 说明情况良好,在页面的最顶端还能看见有绿地黑字的文字“集群监控值:green(5 of 5)”表示一共5个分片 5个分片情况良好
2)再次新建索引
这次我们把分片数设置5,副本数设置为1,为每一个分片添加1个副本,索引名随意’
3)查看健康状况
健康状况变成了黄色底:“集群健康值: yellow (10 of 15)”
点击概览,可以看到新建索引的副本都是灰色的,这是因为副本不会被和分片放在同一个节点上,而我们的es只有一个节点
4)健康状况说明
官方文档:https://www.elastic.co/guide/en/elasticsearch/guide/current/_cluster_health.html
使用get请求访问 ip:9200/_cluster/health
1)打开es-head
2)进入概览
3)选择对应索引的动作按钮
4)点击删除
5)在弹出框中输入删除,点击确定,成功删除
使用delect请求访问 ip:9200/删除的索引名
使用get请求访问 ip:9200/索引名/_analyze
添加body
{
"analyzer": "standard",
"field": "realname",
"text":"so good!"
}
使用post请求访问 ip:9200/索引名/_mapping
添加body
"properties": {
"name": {
"type": "long"
}
}
注:某个属性一旦被建立,就不能修改了,但是可以新增额外属性
使用post请求访问 ip:9200/索引名/_doc/[id]
添加body
{
"id": 1001,
"name": "test-1",
"desc": "这个文档写的真是太好了",
"create_date": "2019-12-24"
}
注:如果索引没有手动建立mappings,那么当插入文档数据的时候,会根据文档类型自动设置属性类型。这个就是es的动态映射,帮我们在index索引库中去建立数据结构的相关配置信息
使用delete请求访问 ip:9200/索引名/_doc/[id]
使用post请求访问 ip:9200/索引名/_doc/[id]/_update
添加body,修改name属性
{
"doc":{
"name": "我现在是一个新的name了"
}
}
使用put请求访问 ip:9200/索引名/_doc/[id]
添加body
{
"id": 1,
"name": "test-2",
"desc": "这个文档写的真是太好了!!!",
"create_date": "2019-12-25"
}
使用get请求访问 ip:9200/索引名/_doc/[id]
使用get请求访问 ip:9200/索引名/_doc/_search
使用head请求访问 ip:9200/索引名/_doc/[id]
当查询、插入、更新一条数据的时候都能看到有一个_version属性,这个属性标识当前数据的版本号,老版本中通过这个属性实现乐观锁,只需要在请求最后加上版本号就可以了
使用post请求访问 ip:9200/索引名/_doc/[id]/_update?version={数值}
但是在新版本中,这个方法已经被淘汰了,采用_seq_no和_primary_term来实现乐观锁
使用post请求访问 ip:9200/索引名/_doc/[id]/_update?if_seq_no={数值}&if_primary_term={数值}
把文本转换为一个个的单词,分词称之为analysis。es默认只对英文语句做分词,中文不支持,每个中文字都会被拆分为独立的个体。
github官网地址:https://github.com/medcl/elasticsearch-analysis-ik
手动安装
自动安装
自动安装ES的版本必须高于5.5.1
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.3.0/elasticsearch-analysis-ik-6.3.0.zip
ik_max_word
会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合,适合 Term Query;
ik_smart
会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”,适合 Phrase 查询。
中文词汇复杂繁多,ik分词器也不能保证所有情况下都能有效的分词,例如:“骚年在认真的学习”,就会被拆分成“骚,年在,认真的,学习”,很明显“年在”并不是一个词,同样的一些专属名词也不能很有效的分词,比如:“印象笔记”,“掘金网“等等,这时候我们就需要为分词器,添加自定义词汇。
vim plugins/ik/config/IKAnalyzer.cfg.xml
在ext_dict属性中添加自定义的词典,需要添加多个字典用分号隔开“;”
IK Analyzer 扩展配置
custom.dic
骚年
印象笔记
掘金网
语法格式为一个json object,内容都是key-value键值对,json可以嵌套。key可以是一些es的关键字,也可以是某个field字段,后面会遇到
使用post请求访问 ip:9200/索引名/_doc/_search
body:
{
"query": {
"match": {
"desc": "掘金网"
}
}
}
使用post请求访问 ip:9200/索引名/_doc/_search
{
"query": {
"exists": {
"field": "desc"
}
}
}
使用post请求访问 ip:9200/索引名/_doc/_search
{
"query": {
"match_all": {}
} ,
"_source": [
"id",
"name",
"age"
]
}
使用post请求访问 ip:9200/索引名/_doc/_search
{
"query": {
"match_all": {}
} ,
"from":10,
"size":10
}
使用term查询的时候,关键词不会被拆分,例如:查询“掘金网”,“掘金网”会被作为一个整体在库中查询,不会拆分成“掘金”、“掘”、“金”、“网”之类的分词进行查询
使用post请求访问 ip:9200/索引名/_doc/_search
{
"query": {
"term": {
"desc": "掘金网"
}
}
}
多个关键词查询
{
"query": {
"term": {
"desc": ["掘金网","骚年"]
}
}
}
使用match查询的时候,关键词会被拆分,例如:查询“掘金网”,会拆分成“掘金”、“掘”、“金”、“网”之类的分词进行查询。
当operater为or的时候(默认为or),只要命中一个拆分的词汇时就可以当做匹配,设置为and的时候,必须所有的分词都匹配到。
minimum_should_match: 最低匹配精度,至少有[分词后的词语个数]x百分百,得出一个数据值取整。举个例子:当前属性设置为70,若一个用户查询检索内容分词后有10个词语,那么匹配度按照 10x70%=7,则desc中至少需要有7个词语匹配,就展示;若分词后有8个,则 8x70%=5.6,则desc中至少需要有5个词语匹配,就展示。同时也支持设置具体的数字,表示匹配单词的个数
使用post请求访问 ip:9200/索引名/_doc/_search
{
"query": {
"match": {
"desc": "掘金网",
"operator": "or",
"minimum_should_match": "60*"
}
}
}
就像用于全文搜索的的match查询一样,当你希望寻找邻近的单词时,match_phrase查询可以帮你达到目的,和match查询类似,match_phrase查询首先解析查询字符串来产生一个词条列表。然后会搜索所有的词条,但只保留包含了所有搜索词条的文档,并且词条的位置要邻接。例如:搜索"大学 毕业",那么数据必须包含“大学”和“毕业”两个单词,并且是连在一起的才会被搜索到。
我们也可以使用“slop”属性指定允许的间隔数,意思是“大学”和“毕业”之间可以出现其他词汇的数量,设置2,就允许中间出现1个或者2个单词,设置100就允许中间至多有100个词汇
使用post请求访问 ip:9200/索引名/_doc/_search
{
"query": {
"match_phrase": {
"desc": {
"query": "大学 毕业",
"slop": 2
}
}
}
}
使用post请求访问 ip:9200/索引名/_doc/_search
{
"query": {
"ids": {
"type": "_doc",
"values": ["1001", "1010", "1008"]
}
}
}
使用post请求访问 ip:9200/索引名/_doc/_search
{
"query": {
"multi_match": {
"query": "皮特帕克",
"fields": ["desc", "name"]
}
}
}
可以使用"^数字"的方式对属性添加权重,例如我们给name属性添加权重,这样搜索的时候name中出现匹配关键词的数据就会显示在前面
{
"query": {
"multi_match": {
"query": "皮特帕克",
"fields": ["desc", "name^10"]
}
}
}
使用post请求访问 ip:9200/索引名/_doc/_search
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "掘金网",
"fields": ["desc", "name"]
}
}, {
"term": {
"sex": 1
"boost": 18
}
}, {
"term": {
"birthday": "1996-01-14"
}
}
]
}
}
}
使用post请求访问 ip:9200/索引名/_doc/_search
{
"query": {
"prefix": {
"name": "皮特帕克"
}
}
}
模糊搜索,并不是指的sql的模糊搜索,而是用户在进行搜索的时候的打字错误现象,搜索引擎会自动纠正,然后尝试匹配索引库中的数据。
官方文档:https://www.elastic.co/guide/cn/elasticsearch/guide/current/fuzzy-match-query.html
使用post请求访问 ip:9200/索引名/_doc/_search
{
"query": {
"fuzzy": {
"desc": "骚年"
}
}
}
多字段查询
{
"query": {
"multi_match": {
"fields": [ "desc", "name"],
"query": "骚年",
"fuzziness": "AUTO"
}
}
}
使用post请求访问 ip:9200/索引名/_doc/_search
{
"query": {
"wildcard": {
"name": "*皮特帕克?"
}
}
}
使用post请求访问 ip:9200/索引名/_doc/_search
{
"query": {
"match": {
"desc": "掘金网"
}
},
"post_filter": {
"range": {
"money": {
"gt": 60,
"lt": 1000
}
}
}
}
使用post请求访问 ip:9200/索引名/_doc/_search
{
"query": {
"match": {
"desc": "掘金网"
}
},
"sort": [
{
"age": "desc"
}, {
"money": "desc"
}
]
}
由于文本会被分词,所以往往要去做排序会报错,通常我们可以为这个字段增加额外的一个附属属性,类型为keyword,用于做排序。
test属性增加keyword创建索引的方法,使用post请求访问 ip:9200/索引名/_mapping
{
"properties": {
"id": {
"type": "long"
},
"name": {
"type": "text",
"analyzer": "ik_max_word",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
在排序的时候使用name下的keyword属性排序,有点内部类的感觉
{
"sort": [
{
"name.keyword": "desc"
}
]
}
使用post请求访问 ip:9200/索引名/_doc/_search
{
"query": {
"match": {
"desc": "掘金网"
}
},
"highlight": {
"pre_tags": [""],
"post_tags": [" "],
"fields": {
"desc": {}
}
}
}