Elasticsearch学习(一)

对于全文检索,只是在刚毕业时研究过sphinx的皮毛,当时项目中选用了sphinx的中文版coreseek,感觉真心强大。而在后来的工作中,也没有再去深入的研究过,而之后看到的文章中,提到最多的只有Solr、Lucene、Elasticsearch这三个基于java的全文检索库,今天工作之余,好好研究一番。

先做了下术语调查,发现Solr与Lucene现在都是Apache基金在维护,Lucene只是一个java框架,如果想使用的话必须要使用java,在程序中集成,了解其原理,所以要求相对较高了。而Solr是最流行的企业级搜索引擎,Solr4 还增加了NoSQL支持,它成熟稳定,还支持html、pdf、doc、xls、json、xml、csv等多种格式的索引。但其缺点也相对明显,数据量增大、搜索效率会降低,实时搜索会阻塞io,效率不高。
Elasticsearch是一个建立在全文搜索引擎 Apache Lucene™ 基础上的搜索引擎,可以说Lucene是当今最先进,最高效的全功能开源搜索引擎框架,使用它做全文搜索时,只需要使用统一开发好的API即可,而不需要了解其背后复杂的Lucene的运行原理。它在全文搜索、实时搜索、分布式搜索、无缝扩展机器处理pb级别数据等方面都非常出色。因此,这里我选择研究Elasticsearch,并记录下自己的所有理解。

  1. 安装
    首先从官网下载安装包:https://www.elastic.co/downloads/elasticsearch,这里我下载的是zip包,版本5.5.1。
    接下来解压文件
    unzip elasticsearch-5.5.1.zip

    接下来安装marvel插件,marvel一个管理和监控的工具,是个插件:

    1
    2
    cd elasticsearch-5.5.1
    ./bin/plugin -i elasticsearch/marvel/latest

    此时,如果想关闭监控,则可以使用以下命令:
    echo 'marvel.agent.enabled: false' >> ./config/elasticsearch.yml

  2. 运行
    ./bin/elasticsearch
    此时如果只有本地访问,则可以修改配置文件 elasticsearch.yml中network.host(注意配置文件格式不是以#开头的要空一格,:后要空一格) 为network.host: 0.0.0.0
    如果想在后台以守护进程模式运行,添加-d参数。

  3. 测试
    执行下面的测试命令即可以看到结果
    curl 'http://localhost:9200/?pretty'
    也可以使用下面命令来关闭它:
    curl -XPOST 'http://localhost:9200/_shutdown'

  4. 查看marvel和sense
    如果你安装了Marvel(作为管理和监控的工具),就可以在浏览器里通过以下地址访问它:
    http://localhost:9200/_plugin/marvel/
    你可以在Marvel中通过点击dashboards,在下拉菜单中访问Sense开发者控制台,或者直接访问以下地址:
    http://localhost:9200/_plugin/marvel/sense/
  5. 端口及通信
    java客户端分为节点客户端(只加入集群、无数据存储)、传输客户端(不加入集群,只请求至节点客户端),两种客户端与集群的交互端口均为9300,假设不开此端口,则不会组 成集群,9200端口则是其他语言通过restful api的形式与Elasticsearch进行通信。

使用

Elasticsearch以json结构的文档存储。Elasticsearch集群可以包含多个索引(indices)(数据库),每一个索引可以包含多个类型(types)(表),每一个类型包含多个文档(documents)(行),然后每个文档包含多个字段(Fields)(列)。倒排索引 传统数据库为特定列增加一个索引,例如B-Tree索引来加速检索。Elasticsearch和Lucene使用一种叫做倒排索引(inverted index)的数据结构来达到相同目的。
与传统关系型数据库的类比图

1
2
Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch -> Indices -> Types -> Documents -> Fields

简单例子如下:

1
2
3
4
5
6
7
8
PUT /megacorp/employee/1
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}

其中megacorp:索引名,employee:类型名;1:这个员工的ID。(另外,再put一次,则更新此文档)

检索

获取的一条数据,保存在_source节点里
GET /megacorp/employee/1

简单搜索,默认搜索结果10条,结果保存在hits数组节点里。
GET /megacorp/employee/_search

查询搜索,结果也在hits数组节点里
GET /megacorp/employee/_search?q=last_name:Smith

使用DSL(Domain Specific Language特定领域语言)语句查询

1
2
3
4
5
6
7
8
GET /megacorp/employee/_search
{
"query" : {
"match" : {
"last_name" : "Smith"
}
}
}

带过滤器的搜索

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
GET /megacorp/employee/_search
{
"query" : {
"filtered" : {
"filter" : {
"range" : {
"age" : { "gt" : 30 } <1>
}
},
"query" : {
"match" : {
"last_name" : "smith" <2>
}
}
}
}
}

搜索短语:如果match_phrase改为match,则会搜索出包含rock或者climbing的结果

1
2
3
4
5
6
7
8
GET /megacorp/employee/_search
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
}
}

搜索结果高亮:

1
2
3
4
5
6
7
8
9
10
11
12
13
GET /megacorp/employee/_search
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
},
"highlight": {
"fields" : {
"about" : {}
}
}
}

聚合,就是完成数据的统计分析,类似于sql的group by
1
2
3
4
5
6
7
8
GET /megacorp/employee/_search
{
"aggs": {
"all_interests": {
"terms": { "field": "interests" }
}
}
}

返回结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
...
"hits": { ... },
"aggregations": {
"all_interests": {
"buckets": [
{
"key": "music",
"doc_count":
},
{
"key": "forestry",
"doc_count": 1
},
{
"key": "sports",
"doc_count": 1
}
]
}
}
}

加上搜索语句的聚合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
GET /megacorp/employee/_search
{
"query": {
"match": {
"last_name": "smith"
}
},
"aggs": {
"all_interests": {
"terms": {
"field": "interests"
}
}
}
}

返回结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
...
"all_interests": {
"buckets": [
{
"key": "music",
"doc_count": 2
},
{
"key": "sports",
"doc_count": 1
}
]
}

聚合也允许分级汇总。例如,让我们统计每种兴趣下职员的平均年龄:

1
2
3
4
5
6
7
8
9
10
11
12
13
GET /megacorp/employee/_search
{
"aggs" : {
"all_interests" : {
"terms" : { "field" : "interests" },
"aggs" : {
"avg_age" : {
"avg" : { "field" : "age" }
}
}
}
}
}

返回结果如下:

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
...
"all_interests": {
"buckets": [
{
"key": "music",
"doc_count": 2,
"avg_age": {
"value": 28.5
}
},
{
"key": "forestry",
"doc_count": 1,
"avg_age": {
"value": 35
}
},
{
"key": "sports",
"doc_count": 1,
"avg_age": {
"value": 25
}
}
]
}

文章目录
  1. 1. 使用
    1. 1.0.1. 检索
    2. 1.0.2. 聚合,就是完成数据的统计分析,类似于sql的group by
|