ElasticSearch:
1)什么是es:
Elasticsearch 是一个分布式的搜索引擎,底层是基于Lucene,是现今最流行的搜索引擎框架.
2)es和lucene的关系.
es和lucene最根本的关系就是,es是一个成品,lucene是一个半成品.
1. 用途方面:
es可以直接应用于企业级项目,
lucene为了搜索引擎底层的建设.
2. 分布式方面:
es本身就是一个分布式的框架,
lucene是单节点的框架。
3. 使用方面:
lucene需要二次开发,
es对外提供了非常友好的API文档.基于RESTful风格,可以通过JAVA API去操作.
4. 打比方:
lucene -> 发动机 + 四个轮胎 + 各种齿轮.
es -> 奥迪A6L
3)es的3个特点:
1. es的高扩展性.
es可以直接横向的扩展,上百台的es机器,就可以处理PB级别数据(1PB=1000个TB).
2. 高可用性.
es会对分片和备份数据分开存放,避免数据丢失.
3. 持久化操作.
es会将每一次成功的写操作,都及时的持久化到本地,避免数据丢失.
4)es的内部结构:
1)一个es集群
2)一个es集群上,有多个es的节点(es服务器)
--- 一个es节点,是一个es进程,类似于一个mysql进程;
3)每一个es的节点上,会有多个es的分片
4)每一个es的分片上,只有一个es的索引(index,此index不是数据库中的那种index)
--- 一个es索引类似于mysql的一个库;
5)每一个es的索引里面,只有一个es的类型(type)
--- 一个es的类型类似于mysql中的一个表;
6)每个es的类型上面,又有多个es的文档(doc|document)
--- 一个es的文档类似于mysql一个表中的一行数据;
7)每个es的文档里面,又有多个es的列(field)
--- 一个es的列相当于mysql的一行数据中的一个字段;
8)每个es的列/字段里面,放的才是真正的数据!
2. es的索引 index.
1. es的索引类似于mysql的一个库.
Ps: es的索引命名要求,全部为小写字母,不能以_开头.
3. es的类型 type
1. es的类型类似于mysql中的一个表.
Ps:
在es的6.0版本中,一个index只可以创建一个type.
在es的7.0版本中,将完全舍弃type。
4. es的文档和列:
1. es的一个文档类似于mysql的一个表中的一行数据。
2. es的一个列类似于mysql中的一行数据中的某一个具体字段数据;
5. es的分片和备份.
1. 一个分片存储的数据量,在10~50G之间,比较好的时候是20个或30G左右;
2. - 分片的作用是:为了避免单台节点压力过大,导致查询效率降低.
方法:当某台节点的压力过大时,可以将该节点上的分片移动到其他压力小的节点上一些;
- es默认创建的索引中,有5个分片。(一个节点上的分片数一旦创建时确定好了,就不能再中途更改.)
3. 备份的作用是:为了避免数据丢失,并且也可以分担查询压力(即,可以进行读操作).
默认的备份数量是1份.
备份数量可以随意改变.
6. es的分片与备份(图解):
节点A,可以存储50个G,有5个分片,每个分片存储10个G;(如上图所示)
节点A的压力过大,所以将一些分片移交给其他的节点,缓解压力;(如下图所示)
5) 索引的操作.
1. 创建索引,然后指定类型结构.
PUT /索引 // 增加一个索引,相当于数据库中的一个库
{
"settings": { // 设置
"number_of_shards": 3, // 指定分片数,默认是5
"number_of_replicas": 1 // 指定备份数,默认是1
}
}
PUT /索引/类型/_mappings // 创建一个索引中的类型,相当于数据库中的某个库中的一个表
{
"properties": { // 通过"properties"来指定该类型有哪些列,相当于指定数据库的表中有哪些字段
"列名": { // 字段名/列名
"type": "类型" // 字段名的类型
},
"列名": {
"type": "时间类型".
"format": "格式化方式" // 字段名的格式
}
}
}
GET /索引 // 查询某个索引
eg:
// 第一步:先添加一个索引(相当于创建一个数据库)
PUT /qf
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
}
}
// 第二步:为名为“qf”的索引的"people"类型,添加几个列(相当于在某个数据库中,创建几张表)
PUT /qf/people/_mappings
{
"properties": {
"name":{ // 定义一个列,列名叫:name
"type": "text" // name列的类型为:text,即字符串
},
"age":{ // 定义一个列,列名叫age
"type": "integer" // age列的类型为Integer,即数字类型
},
"birthday":{ // 定义一个列,列名为birthday
"type": "date", // 该列的数据类型为date
"format": "yyyy-MM-dd" // 该列的格式为:"yyyy-MM-dd"
}
}
}
// 第三步:查询看一下:
GET /qf
上述两步合二为一步:
PUT /索引名
{
"settings":{
"number_of_shards":3, // 设置分片数
"number_of_replicas":1 // 设置备份数
},
"mappings":{
"类型名":{
"properties":{
"列名1":{
"type":"text" // 该列的数据类型
},
"列名2":{
"type":"date", // 该列的数据类型
"format":"yyyy-MM-dd" // 该列的格式
}
}
}
}
}
eg:
PUT /qf2
{
"settings": {
"number_of_shards": 3, // 指定分片数
"number_of_replicas": 1 // 指定备份数
},
"mappings": {
"people":{ // 指定是索引"qf2"的"people"类型
"properties":{
"name":{ // 列名name
"type":"text" // 该列的类型
},
"age":{ // 列名age
"type":"integer" // 该列的类型
},
"birthday":{ // 列名birthday
"type":"date", // 该列的数据类型
"format":"yyyy-MM-dd" // 该列的格式
}
}
}
}
}
2. 删除索引.
DELETE /qf
3. 是否可以作为查询条件&指定分词器类型
PUT /qf
{
"settings": {
"number_of_shards": 5,
"number_of_replicas": 1
},
"mappings": {
"people": {
"properties": {
"name": {
"type": "text",
"index": true, // 默认就是true,但如果为false,那意思就是这个列(即name列)是不允许作为查询条件的
"analyzer": "ik_max_word" // 指定分词器的类型为ik分词器
},
"country": {
"type": "keyword" // 该country列的类型为关键字(仍是字符串类型),即不允许分词器拆分;
},
"age": {
"type": "integer"
},
"birthday": {
"type": "date",
"format": "yyyy-MM-dd"
}
}
}
}
}
指定的
type: 类型.
index: 是否可以被索引. 默认是true(进行分词搜索)
anaylzer: 指定分词器.
format: 格式化方式
4. 追加一个field. (暂不支持修改/删除一个field)
POST /qf/people/_mapping // 为"qf"索引的people类型追加一个列
{
"properties": {
"country": { // 列名为"country"
"type": "keyword" // 该列的类型为”keyword“关键字
}
}
}
5. es的类型.
文本类型:
text: 可以被分词.
keyword: 不可以被分词,必须==查询.
数值类型:
整型: byte,short,integer,long.
浮点型: double, float, half_float
高精度浮点型: scaled_float -> 一般需要指定一个因子,如果指定100的话,原数据为1.28,在存储到es时,存128,当查询返回时,es再除以因为,返回1.28
时间类型:
date: 时间类型 -> 一般配合format使用.format只可以指定"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
布尔类型:
true || "true"
false || "false"
Binary:
暂时只支持使用Base64编码的内容.
特殊类型:
ip: 支持ipv4和ipv6.
6) 基本查询.
1. match.
可以实现全文搜索, 可以针对text类型.
match和term的区别:
match:在匹配时会对所查找的关键词进行分词,然后按分词匹配查找;
term:只针对keyword关键字进行查找;
一般模糊查找的时候,多用match,而精确查找时可以使用term。
1.1 match_all.
查询全部数据,并且不会计算分数.
//sms-logs-index:固定称呼,意思是索引; _search:说明要做查询操作
POST /sms-logs-index/_search
{
"query": {
"match_all": {}
}
}
1.2 条件查询. (一个字段一个值)
针对一个字段做全文检索,并且会根据指定的分词器分词,并且计算分数
POST /sms-logs-index/_search
{
"query": {
"match": {
"smsContent": "北京"
}
}
}
1.3 multi查询. (多个字段一个值)
针对多个字段用一个值做全文检索,并且会根据指定的分词器分词,并且计算分数。
POST /sms-logs-index/_search
{
"query": {
"multi_match": {
"query": "北京",
"fields": ["province","smsContent"]
}
}
}