ES即简单又复杂,你可以快速的实现全文检索,又需要了解复杂的REST API。本篇就通过一些简单的搜索命令,帮助你理解ES的相关应用。虽然不能让你理解ES的原理设计,但是可以帮助你理解ES,探寻更多的特性。

其他相关的内容参考:Elasticsearch官方文档翻译

样例数据

为了更好的使用和理解ES,没有点样例数据还是不好模拟的。这里提供了一份官网上的数据,accounts.json。如果需要的话,也可以去这个网址玩玩,它可以帮助你自定义写随机的JSON数据

首先开启你的ES,然后执行下面的命令,windows下需要自己安装curl、也可以使用cygwin模拟curl命令:

curl -XPOST 'localhost:9200/bank/account/_bulk?pretty' --data-binary  @accounts.json

注意:

1 需要在accounts.json所在的目录运行curl命令。

2 localhost:9200是ES得访问地址和端口

3 bank是索引的名称

4 account是类型的名称

5 索引和类型的名称在文件中如果有定义,可以省略;如果没有则必须要指定

6 _bulk是rest得命令,可以批量执行多个操作(操作是在json文件中定义的,原理可以参考之前的翻译)

7 pretty是将返回的信息以可读的JSON形式返回。

执行完上述的命令后,可以通过下面的命令查询:

curl 'localhost:9200/_cat/indices?v'
health index pri rep docs.count docs.deleted store.size pri.store.size
yellow bank .4kb .4kb

搜索API

ES提供了两种搜索的方式:请求参数方式请求体方式

请求参数方式

curl 'localhost:9200/bank/_search?q=*&pretty'

其中bank是查询的索引名称,q后面跟着搜索的条件:q=*表示查询所有的内容

请求体方式(推荐这种方式)

curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match_all": {} }
}'

这种方式会把查询的内容放入body中,会造成一定的开销,但是易于理解。在平时的练习中,推荐这种方式。

返回的内容

{
"took" : ,
"timed_out" : false,
"_shards" : {
"total" : ,
"successful" : ,
"failed" :
},
"hits" : {
"total" : ,
"max_score" : 1.0,
"hits" : [ {
"_index" : "bank",
"_type" : "account",
"_id" : "",
"_score" : 1.0, "_source" : {"account_number":,"balance":,"firstname":"Amber","lastname":"Duke","age":,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
}, {
"_index" : "bank",
"_type" : "account",
"_id" : "",
"_score" : 1.0, "_source" : {"account_number":,"balance":,"firstname":"Hattie","lastname":"Bond","age":,"gender":"M","address":"671 Bristol Street","employer":"Netagy","email":"hattiebond@netagy.com","city":"Dante","state":"TN"}
}, {
"_index" : "bank",
"_type" : "account",
"_id" : "",

返回的内容大致可以如下讲解:

took:是查询花费的时间,毫秒单位

time_out:标识查询是否超时

_shards:描述了查询分片的信息,查询了多少个分片、成功的分片数量、失败的分片数量等

hits:搜索的结果,total是全部的满足的文档数目,hits是返回的实际数目(默认是10)

_score是文档的分数信息,与排名相关度有关,参考各大搜索引擎的搜索结果,就容易理解。

由于ES是一次性返回所有的数据,因此理解返回的内容是很必要的。它不像传统的SQL是先返回数据的一个子集,再通过数据库端的游标不断的返回数据(由于对传统的数据库理解的不深,这里有错还望指正)。

查询语言DSL

ES支持一种JSON格式的查询,叫做DSL,domain specific language。这门语言刚开始比较难理解,因此通过几个简单的例子开始:

下面的命令,可以搜索全部的文档:

{
"query": { "match_all": {} }
}

query定义了查询,match_all声明了查询的类型。还有其他的参数可以控制返回的结果:

curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match_all": {} },
"size":
}'

上面的命令返回了所有文档数据中的第一条文档。如果size不指定,那么默认返回10条。

下面的命令请求了第10-20的文档。

curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match_all": {} },
"from": ,
"size":
}'

下面的命令指定了文档返回的排序方式:

curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match_all": {} },
"sort": { "balance": { "order": "desc" } }
}'

执行搜索

上面了解了基本的搜索语句,下面就开始深入一些常用的DSL了。

之前的返回数据都是返回文档的所有内容,这种对于网络的开销肯定是有影响的,下面的例子就指定了返回特定的字段:

curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match_all": {} },
"_source": ["account_number", "balance"]
}'

再回到query,之前的查询都是查询所有的文档,并不能称之为搜索引擎。下面就通过match方式查询特定字段的特定内容,比如查询余额为20的账户信息:

curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match": { "account_number": } }
}'

查询地址为mill的信息:

curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match": { "address": "mill" } }
}'

查询地址为mill或者lane的信息:

curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match": { "address": "mill lane" } }
}'

如果我们想要返回同时包含mill和lane的,可以通过match_phrase查询:

curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": { "match_phrase": { "address": "mill lane" } }
}'

ES提供了bool查询,可以把很多小的查询组成一个更为复杂的查询,比如查询同时包含mill和lane的文档:

curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"must": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}'

修改bool参数,可以改为查询包含mill或者lane的文档:

curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"should": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}'

也可以改写为must_not,排除包含mill和lane的文档:

curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"must_not": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}'

bool查询可以同时使用must, should, must_not组成一个复杂的查询:

curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"must": [
{ "match": { "age": "" } }
],
"must_not": [
{ "match": { "state": "ID" } }
]
}
}
}'

过滤查询

之前说过score字段指定了文档的分数,使用查询会计算文档的分数,最后通过分数确定哪些文档更相关,返回哪些文档。

有的时候我们可能对分数不感兴趣,就可以使用filter进行过滤,它不会去计算分值,因此效率也就更高一些。

filter过滤可以嵌套在bool查询内部使用,比如想要查询在2000-3000范围内的所有文档,可以执行下面的命令:

curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"query": {
"bool": {
"must": { "match_all": {} },
"filter": {
"range": {
"balance": {
"gte": ,
"lte":
}
}
}
}
}
}'

ES除了上面介绍过的范围查询range、match_all、match、bool、filter还有很多其他的查询方式,这里就先不一一说明了。

聚合

聚合提供了用户进行分组和数理统计的能力,可以把聚合理解成SQL中的GROUP BY和分组函数。在ES中,你可以在一次搜索查询的时间内,即完成搜索操作也完成聚合操作,这样就降低了多次使用REST API造成的网络开销。

下面就是通过terms聚合的简单样例:

curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"size": ,
"aggs": {
"group_by_state": {
"terms": {
"field": "state"
}
}
}
}'

它类似于SQL中的下面的语句:

SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC

返回的数据:

"hits" : {
"total" : ,
"max_score" : 0.0,
"hits" : [ ]
},
"aggregations" : {
"group_by_state" : {
"buckets" : [ {
"key" : "al",
"doc_count" :
}, {
"key" : "tx",
"doc_count" :
}, {
"key" : "id",
"doc_count" :
}, {
"key" : "ma",
"doc_count" :
}, {
"key" : "md",
"doc_count" :
}, {
"key" : "pa",
"doc_count" :
}, {
"key" : "dc",
"doc_count" :
}, {
"key" : "me",
"doc_count" :
}, {
"key" : "mo",
"doc_count" :
}, {
"key" : "nd",
"doc_count" :
} ]
}
}
}

由于size设置为0,它并没有返回文档的信息,只是返回了聚合的结果。

比如统计不同账户状态下的平均余额:

curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"size": ,
"aggs": {
"group_by_state": {
"terms": {
"field": "state"
},
"aggs": {
"average_balance": {
"avg": {
"field": "balance"
}
}
}
}
}
}'

聚合支持嵌套,举个例子,先按范围分组,在统计不同性别的账户余额:

curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
{
"size": ,
"aggs": {
"group_by_age": {
"range": {
"field": "age",
"ranges": [
{
"from": ,
"to":
},
{
"from": ,
"to":
},
{
"from": ,
"to":
}
]
},
"aggs": {
"group_by_gender": {
"terms": {
"field": "gender"
},
"aggs": {
"average_balance": {
"avg": {
"field": "balance"
}
}
}
}
}
}
}
}'

聚合可以实现很多复杂的功能,而且ES也提供了很多复杂的聚合,这里作为引导篇,也不过多介绍了。

对于基本的数据搜索大致就是上面讲述的样子,熟悉了一些常用的API,入门还是很简单的,倒是要熟练使用ES,还是需要掌握各种搜索查询的命令,以及ES内部的原理。

Elasticsearch 数据搜索篇·【入门级干货】的更多相关文章

  1. Elasticsearch 数据搜索篇·【入门级干货】===转

    ES即简单又复杂,你可以快速的实现全文检索,又需要了解复杂的REST API.本篇就通过一些简单的搜索命令,帮助你理解ES的相关应用.虽然不能让你理解ES的原理设计,但是可以帮助你理解ES,探寻更多的 ...

  2. Elasticsearch 数据搜索篇

    curl 'localhost:9200/_cat/indices?v' health index pri rep docs.count docs.deleted store.size pri.sto ...

  3. Elasticsearch 数据搜索

    ES即简单又复杂,你可以快速的实现全文检索,又需要了解复杂的REST API.本篇就通过一些简单的搜索命令,帮助你理解ES的相关应用.虽然不能让你理解ES的原理设计,但是可以帮助你理解ES,探寻更多的 ...

  4. Spring Boot 揭秘与实战(二) 数据存储篇 - ElasticSearch

    文章目录 1. 版本须知 2. 环境依赖 3. 数据源 3.1. 方案一 使用 Spring Boot 默认配置 3.2. 方案二 手动创建 4. 业务操作5. 总结 4.1. 实体对象 4.2. D ...

  5. ElasticSearch查询 第一篇:搜索API

    <ElasticSearch查询>目录导航: ElasticSearch查询 第一篇:搜索API ElasticSearch查询 第二篇:文档更新 ElasticSearch查询 第三篇: ...

  6. Spring Boot干货系列:(八)数据存储篇-SQL关系型数据库之JdbcTemplate的使用

    Spring Boot干货系列:(八)数据存储篇-SQL关系型数据库之JdbcTemplate的使用 原创 2017-04-13 嘟嘟MD 嘟爷java超神学堂 前言 前面几章介绍了一些基础,但都是静 ...

  7. Elasticsearch系列---搜索分页和deep paging问题

    概要 本篇从介绍搜索分页为起点,简单阐述分页式数据搜索与原有集中式数据搜索思维方式的差异,就分页问题对deep paging问题的现象进行分析,最后介绍分页式系统top N的案例. 搜索分页语法 El ...

  8. ElasticSearch入门 第二篇:集群配置

    这是ElasticSearch 2.4 版本系列的第二篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...

  9. ElasticSearch入门 第九篇:实现正则表达式查询的思路

    这是ElasticSearch 2.4 版本系列的第九篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...

随机推荐

  1. 搭建coreseek(sphinx+mmseg3)详细安装配置+php之sphinx扩展安装+php调用示例

    http://blog.csdn.net/e421083458/article/details/21529969 常用的命令 ps -ef|grep searchd 如果你开了search服务后,你命 ...

  2. Replication的犄角旮旯(四)--关于事务复制的监控

    <Replication的犄角旮旯>系列导读 Replication的犄角旮旯(一)--变更订阅端表名的应用场景 Replication的犄角旮旯(二)--寻找订阅端丢失的记录 Repli ...

  3. 开始VS 2012中LightSwitch系列的第3部分:我该选择哪一个屏幕模板

    [原文发表地址]  Beginning LightSwitch in VS 2012 Part 3: Screen Templates, Which One Do I Choose? [原文发表时间] ...

  4. 图解js中常用的判断浏览器窗体、用户屏幕可视区域大小位置的方法

    有时我们需要获得浏览器窗口或屏幕的大小.窗口下拉框下拉的距离等数据,对应这些需求,js中提供了不少解决方法,只是数量稍多容易混淆它们各自的意义,下面咱们用图例来解释下12个常见对象属性的作用. 其中有 ...

  5. 团队项目——站立会议 DAY11

    团队项目--站立会议 DAY11        团队成员介绍(5人):张靖颜.何玥.钟灵毓秀.赵莹.王梓萱        今日(2016/5/20),站立会议已进行了两周时间,将这一周所遇到的问题和心 ...

  6. 通过分析iframe和无阻塞脚本关系能让我们更懂iframe

    在我上篇文章里,我提到一种使用iframe完成无阻塞脚本加载的方式,因为我对iframe的偏见很大,所以上篇文章里我没有展开讨论这个问题. 文章发表后有位网友问了我这样一个问题,下面是他问题的原文,如 ...

  7. Vue.js线程机制问题还是数据双向绑定有延迟的问题

    最近用select2做一个下拉多选,若只是从后端获取一个列表渲染还好说,没有任何问题.但要用select2对数据初始化时进行selected的默认选项进行显示,就出现问题了. vm.$set('are ...

  8. 知方可补不足~SqlServer连接的复用MultipleActiveResultSets

    回到目录 MultipleActiveResultSets可以使数据库连接复用,但当你上了moebius这种集群工具后,这个选项不能开启(默认是false),当你使用EF等ORM工具时,这个选项会默认 ...

  9. Atitit 编程语言常用算法attilax总结

    Atitit 编程语言常用算法attilax总结 1. 编译算法分类and   数据操作算法.1 1.1. Tab driver stat  状态转换表格算法1 1.2. Nest case 词法分析 ...

  10. 遍历后台的List,让前台的多选宽被选中

    后端代码: /** * 获取优惠卷分页信息 * * * @param ph * 包括查询条件以及分页查询条件 * */ @Override public DataGrid<AppCmsCoupo ...