Elasticsearch 数据搜索
ES即简单又复杂,你可以快速的实现全文检索,又需要了解复杂的REST API。本篇就通过一些简单的搜索命令,帮助你理解ES的相关应用。虽然不能让你理解ES的原理设计,但是可以帮助你理解ES,探寻更多的特性。
搜索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" : 26, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "failed" : 0 }, "hits" : { "total" : 1000, "max_score" : 1.0, "hits" : [ { "_index" : "bank", "_type" : "account", "_id" : "1", "_score" : 1.0, "_source" : a }, { "_index" : "bank", "_type" : "account", "_id" : "6", "_score" : 1.0, "_source" : b }] } }
返回的内容大致可以如下讲解:
- 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": 1 }'
上面的命令返回了所有文档数据中的第一条文档。如果size不指定,那么默认返回10条。
下面的命令请求了第10-20的文档。
curl -XPOST 'localhost:9200/bank/_search?pretty' -d ' { "query": { "match_all": {} }, "from": 10, "size": 10 }'
下面的命令指定了文档返回的排序方式:
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": 20 } } }'
查询地址为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": "40" } } ], "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": 20000, "lte": 30000 } } } } } }'
ES除了上面介绍过的范围查询range、match_all、match、bool、filter还有很多其他的查询方式,这里就先不一一说明了。
聚合
聚合提供了用户进行分组和数理统计的能力,可以把聚合理解成SQL中的GROUP BY和分组函数。在ES中,你可以在一次搜索查询的时间内,即完成搜索操作也完成聚合操作,这样就降低了多次使用REST API造成的网络开销。
下面就是通过terms聚合的简单样例:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d ' { "size": 0, "aggs": { "group_by_state": { "terms": { "field": "state" } } } }'
它类似于SQL中的下面的语句:
SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC
返回的数据:
"hits" : { "total" : 1000, "max_score" : 0.0, "hits" : [ ] }, "aggregations" : { "group_by_state" : { "buckets" : [ { "key" : "al", "doc_count" : 21 }, { "key" : "tx", "doc_count" : 17 }, { "key" : "id", "doc_count" : 15 }, { "key" : "ma", "doc_count" : 15 }, { "key" : "md", "doc_count" : 15 }, { "key" : "pa", "doc_count" : 15 }, { "key" : "dc", "doc_count" : 14 }, { "key" : "me", "doc_count" : 14 }, { "key" : "mo", "doc_count" : 14 }, { "key" : "nd", "doc_count" : 14 } ] } } }
由于size设置为0,它并没有返回文档的信息,只是返回了聚合的结果。
比如统计不同账户状态下的平均余额:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d ' { "size": 0, "aggs": { "group_by_state": { "terms": { "field": "state" }, "aggs": { "average_balance": { "avg": { "field": "balance" } } } } } }'
聚合支持嵌套,举个例子,先按范围分组,在统计不同性别的账户余额:
curl -XPOST 'localhost:9200/bank/_search?pretty' -d ' { "size": 0, "aggs": { "group_by_age": { "range": { "field": "age", "ranges": [ { "from": 20, "to": 30 }, { "from": 30, "to": 40 }, { "from": 40, "to": 50 } ] }, "aggs": { "group_by_gender": { "terms": { "field": "gender" }, "aggs": { "average_balance": { "avg": { "field": "balance" } } } } } } } }'
聚合可以实现很多复杂的功能,而且ES也提供了很多复杂的聚合,这里作为引导篇。
本文转载自 linkedkeeper.com
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Spring核心——字符串到实体转换
笼统的说一个系统主要是由3个部分组成的: 1、执行程序:主要负责处理业务逻辑,对接用户操作。 2、内部数据:嵌套在源码中的数据,用于指导程序运行。 3、外部数据:业务数据,外部配置数据。 内部数据本身就是程序的一部分,在Java中这些数据通常停留在类的静态成员变量中。而外部数据往往与代码无关,所以对于程序而言要“读懂”它们需要进行一些前置处理。例如用户在前端页面提交的数据我们从RequestContext中获取的数据类型都是字符串,而我们的业务需要将字符串转换成数字、列表、对象等等,这就引入了我们接下来要介绍的内容——数据类型转换。 JavaBean对于J2SE或者J2EE而言有着非常重要的意义,ORACLE为了统一各个组织对JavaBean的使用方式制定了详尽的JavaBean规范,包括BeanInfo、PropertyEditor、PropertyEditorSupport等方面的内容。本文会涉及到JavaBean的一些规范,但是重点是介绍Spring的数据管理。 (可执行代码请到本人gitee库下载,本文的代码在chkui.springcore.example.hybrid.be...
- 下一篇
Java 异步处理简单实践
Java 异步处理简单实践 同步与异步 通常同步意味着一个任务的某个处理过程会对多个线程在用串行化处理,而异步则意味着某个处理过程可以允许多个线程同时处理。 异步通常代表着更好的性能,因为它很大程度上依赖于缓冲,是典型的使用空间换时间的做法,例如在计算机当中,高速缓存作为cpu和磁盘io之间的缓冲地带协调cpu高速计算能力和磁盘的低速读写能力。 volatile 应用场景:检查一个应用执行关闭或中断状态。因为此关键字拒绝了虚拟对一个变量多次赋值时的优化从而保证了虚拟机一定会检查被该关键字修饰的变量的状态变化。 CountDownLatch 应用场景:控制在一组线程操作执行完成之前当前线程一直处于等待。例如在主线程中执行await()方法阻塞主线程,在工作线程执行完逻辑后执行countDown()方法。 本文示例场景: 1,从控制台发送消息到消息服务器(由一个队列模拟)。 2,将消息队列写入到文件(对写文件的操作设置延时以模拟性能瓶颈)。 3,消息服务器作为控制台和文件写入之间的缓冲区。 示例代码: 注:往消息队列添加消息可以通过for循...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Red5直播服务器,属于Java语言的直播服务器
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS7设置SWAP分区,小内存服务器的救世主
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Hadoop3单机部署,实现最简伪集群
- Mario游戏-低调大师作品
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程