ElasticSearch:

1)什么是es:

  1. 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的内部结构:

5_elasticserch - 图1

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的分片与备份(图解):

5_elasticserch - 图2

    节点A,可以存储50个G,有5个分片,每个分片存储10个G;(如上图所示)

    节点A的压力过大,所以将一些分片移交给其他的节点,缓解压力;(如下图所示)

5_elasticserch - 图3

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"]
    }
  }
}