Elasticsearch快速入门

ES是什么

ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。我们可以这么去理解:

  • 分布式的实时文件存储,每个字段都被索引并可被搜索
  • 分布式的实时分析搜索引擎
  • 可以扩展到上百台服务器,处理PB级结构化或非结构化数据

索引,类型,文档的含义

在搜索引擎之前,使用的基本上都是关系型的数据库(mysql,mssql,oracle),在关系型数据库中有Database,Table和row.

对于es来说,有Index ,Type,Document来与之对应,关系如下:

关系数据库 数据库
ES Index Type Document


注意: 每个 Index (即数据库)的名字必须是小写。
Elastic 6.x 版只允许每个 Index 包含一个 Type,7.x 版将会彻底移除 Type

Index管理


创建Index

1
2
3

put /fwdatabase

成功返回:

1
2
3
4
5
6
{
"acknowledged":true,
"shards_acknowledged":true,
"index":"fwdatabase"
}

查询系统Index

1
2
3

GET /_cat/indices?v

es入门

或者用_mget返回json信息

1
GET /_mget   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"docs": [
{
"_index": "fwdatabase",
"_type": "order",
"_id": "nCYUrGgBn1FEHZKMQWsk",
"found": false
},
{
"_index": "fwdatabase1",
"_type": "order",
"_id": "myYUrGgBn1FEHZKMQWsk",
"_version": 1,
"found": true,
"_source": {}
}
]
}

删除Index

1
2
3

delete /fwdatabase

Type 创建和删除


新建type

在关系型数据库中,我们需要指定表字段和字段的类型,在ES也可以松散的定义数据,也可以订制指定的类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
put  /fwdatabase/_mapping/order
{
"properties": {
"orderId": {
"type": "keyword"
},
"shortTime": {
"type": "date"
},
"name": {
"type": "keyword"
},
"amount": {
"type": "double"
},
"desc": {
"type": "text"
}
}
}

curl -X PUT -H ‘Content-type: application/json’ -d ‘{“properties”:{“orderId”:{“type”:”keyword”},”shortTime”:{“type”:”keyword”},”amount”:{“type”:”double”},”desc”:{“type”:”text”}}}’ http://localhost:9200/fwdatabase/_mapping/order

查询type

  1. 查询Index所包含的Type

    1
    2
    3

    GET /_mapping?pretty=true

    es入门

  1. 其他一些查询
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /_search
    在所有索引的所有类型中搜索

    /gb/_search
    在索引gb的所有类型中搜索

    /gb,us/_search
    在索引gb和us的所有类型中搜索

    /g*,u*/_search
    在以g或u开头的索引的所有类型中搜索

    /gb/user/_search
    在索引gb的类型user中搜索

    /gb,us/user,tweet/_search
    在索引gb和us的类型为user和tweet中搜索

    /_all/order,bill/_search
    在所有索引中搜索order,bill类型

修改type和删除type

修改Type一般可以只对数据进行局部更新,或者删除当前Index后重新创建一个新的type,此处略去不去过多的讲述。

document的管理


document相当于mysql中的行数据,我们可以通过接口对es的数据进行管理。

插入数据

  1. 单条插入数据

    1
    2
    3
    4
    5
    6
    7
    POST  /fwdatabase/order
    {
    "orderId":"10000",
    "name":"test",
    "amount":12.09,
    "desc":"测试"
    }

    插入成功返回信息:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    "_index": "fwdatabase", //index名称
    "_type": "order", //类型名称
    "_id": "aI9AvGgBpdtUL3hsAU2l", //生成的id
    "_version": 1,//版本号
    "result": "created",
    "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
    },
    "_seq_no": 0,
    "_primary_term": 2
    }

    插入的数据可以通过_search接口查询出来:

    1
    2
    3

    GET /fwdatabase/order/_search

    查询结果和相关注释如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    {
    "took": 4, //耗时
    "timed_out": false,//是否超时
    "_shards": { //分片信息
    "total": 5, //分片数量
    "successful": 5,//
    "skipped": 0,
    "failed": 0
    },
    "hits": {
    "total": 1,//查询命中的记录数
    "max_score": 1,
    "hits": [
    {
    "_index": "fwdatabase",//索引名称
    "_type": "order",
    "_id": "RH0AvWgBNfbilfsxyX-V",//自增ID
    "_score": 1,//相关得分
    "_source": {//返回数据
    "orderId": "10000",
    "name": "test",
    "amount": 12.09,
    "desc": "测试"
    }
    }
    ]
    }
    }

其中 _index 和 _type是对应的索引和类型的名称,_id是系统自动指定的唯一标识的主键。也可以自己之指定:

1
2
3
4
5
6
7
8
POST  /fwdatabase/order/1 //这里指定_id的值
{
"_id":1,
"orderId":"10000",
"name":"test",
"amount":12.09,
"desc":"测试"
}

批量增加数据

批量插入数据可以减少与es的网络请求,从而加快插入的效率,调用的是_bulk的接口,写法如下:(为了方便后面的演示,在此处插入点数据):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

{"index":{}}
{"shortTime":"2019-01-05","orderId":"10000","name":"user1","amount":12.09,"desc":"水果收入"}
{"index":{}}
{"shortTime":"2019-01-08","orderId":"10001","name":"user2","amount":110.00,"desc":"苹果收入"}
{"index":{}}
{"shortTime":"2019-01-09","orderId":"10002","name":"user3","amount":53.98,"desc":"香蕉收入"}
{"index":{}}
{"shortTime":"2019-01-08","orderId":"10003","name":"user4","amount":-53.09,"desc":"支出"}
{"index":{}}
{"shortTime":"2019-01-18","orderId":"10004","name":"user5","amount":-66.00,"desc":"转账"}
{"index":{}}
{"shortTime":"2019-01-28","orderId":"10005","name":"user6","amount":-102.50,"desc":"转账"}
{"index":{}}
{"shortTime":"2019-01-08","orderId":"10006","name":"user7","amount":32.59,"desc":"收入"}
{"index":{}}
{"shortTime":"2019-01-08","orderId":"10007","name":"user8","amount":-10.09,"desc":"支出"}
{"index":{}}
{"shortTime":"2019-01-06","orderId":"10008","name":"user9","amount":-11.50,"desc":"种子支出"}
{"index":{}}
{"shortTime":"2019-01-08","orderId":"10009","name":"user10","amount":305.49,"desc":"其他入账"}
{"index":{}}
{"shortTime":"2019-01-04","orderId":"10010","name":"user11","amount":1112.09,"desc":"分红"}
{"index":{}}
{"shortTime":"2019-01-08","orderId":"10011","name":"user12","amount":-48.45,"desc":"支出"}
{"index":{}}
{"shortTime":"2019-01-06","orderId":"10012","name":"user13","amount":-59.20,"desc":"税收支出"}

插入完成后的数据

es入门

更新数据

  1. 按id更新数据

    1
    2
    3
    4
    5
    6
    7
    POST fwdatabase/order/1 
    {
    "orderId":"10001",
    "name":"userTest",
    "amount":122.76,
    "desc":"测试更新"
    }
  2. 批量更新

    批量更新与批量插入是同一个接口,在批量插入的时候指定_id,es会自动选择插入和更新。

    1
    2
    3
    4
    5
    POST /fwdatabase/order/_bulk
    { "index": { "_id": "RH0AvWgBNfbilfsxyX-V" }}
    {"orderId":"111111", "name":"user", "amount":12.09, "desc":"测试批量更新"}
    { "index": { "_id": "Pn0AvWgBNfbilfsxyX-V" }}
    {"orderId":"222222", "name":"user", "amount":112.09, "desc":"测试批量更新"}

    es入门

  3. 局部更新

    局部更新可以增加一个document的字段,其他数据保持不变:

    1
    2
    3
    4
    5
    6
    7
    8

    POST /fwdatabase/order/PX0AvWgBNfbilfsxyX-V/_update
    {
    "doc" : {
    "tags" : "testing"
    }
    }

    id=PX0AvWgBNfbilfsxyX-V的数据增加一个tags列。

删除数据

  1. 按id删除

    1
    DELETE fwdatabase/order/1

    删除Id为1的数据。
    或者用query的查询删除也可以:

    1
    2
    3
    4
    5
    6
    7
    8
    POST  fwdatabase/order/_delete_by_query
    {
    "query": {
    "term": {
    "_id": "O30AvWgBNfbilfsxyX-V"
    }
    }
    }
> term是精确查询,后面查询会讲到
  1. 按查询结果删除

    1
    2
    3
    4
    5
    6
    POST  fwdatabase/order/_delete_by_query
    {
    "query": {
    "match_all": {}
    }
    }

查询数据


es查询分为两种,一种是参数存在与url中,形式/index/type/_search?q=_id:1
如:

1
GET /fwdatabase/order/_search?q=_id:P30AvWgBNfbilfsxyX-V

称为: Search Lite API

一种是利用POST方法提交json数据,实现查询(上面已经演示),称为:DSL查询

dsl更具有可读性,推荐使用。

  1. Search Lite API查询

    由于这种查询方式,不太场采用,只是简单介绍下,不做深入探究。

    1.1. 按ID查询

    1
    GET /index/type/_search?q=_id:1

    1.2. 查询指定的字段

    只查询orderId,amount字段。

    1
    GET  /fwdatabase/order/_search?q=_id:P30AvWgBNfbilfsxyX-V&_source=orderId,amount   

    1.3. 排序和分页

    排序:

    1
    GET  /fwdatabase/order/_search?sort=amount:desc  

    分页:

    1
    GET  /fwdatabase/order/_search?sort=amount:desc&from=0&size=2 

  1. (DSL)查询
    2.1 精确查询

    精确查询相当于mysql中的等于(=),在es中使用的term关键字

    • 查询user用户的收入和支出情况:

      1
      2
      3
      4
      5
      6
      7
      POST  /fwdatabase/order/_search
      {
      "query": {
      "term": {"name":"user"}
      }
      }

    • 查询user和user1的收支情况:

      1
      2
      3
      4
      5
      6
      7
      POST  /fwdatabase/order/_search
      {
      "query": {
      "terms": {"name":["user","user1"]}
      }
      }

    • 多个精确条件查询

      这个是需要其他高级的表达式,此处先不着急,留个问题在这。

      2.2 模糊查询

    • match

      1
      2
      3
      4
      5
      6
      7
      POST  /fwdatabase/order/_search
      {
      "query": {
      "match": {"desc":"收入"}
      }
      }

      查询出所有desc为包含收入的数据。

      如果用match下指定了一个确切值,在遇到数字,日期,布尔值或者not_analyzed 的字符串时,将是精确搜索. 

      1
      2
      3
      4
      5
      6
      POST  /fwdatabase/order/_search
      {
      "query": {
      "match": {"name":"user"}
      }
      }

2.3 分页

1
2
3
4
5
6
POST  /fwdatabase/order/_search
{

"from":0,
"size":3
}

2.4 排序

  • 默认正序

    1
    2
    3
    4
    5
    6
    {
    "from":0,
    "size":10,
    "sort":"amount"

    }
  • 倒序

    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
    "from": 0,
    "size": 10,
    "sort": {
    "amount": {
    "order": "desc"
    }
    }
    }
  • 多条件排序

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    "sort": [
    {
    "amount": {
    "order": "desc"
    }
    },
    {
    "orderId": {
    "order": "desc"
    }
    }
    ]
    }