Elasticsearch应用开发入门

为什么是Elasticsearch?

相信广大网友对今年2月28日百度宕机的事情有所感受,就算没有亲身经历到也应该有所耳闻。

由此可见在我们的生命中,度娘已经成为一到迈不过去的坎了,熟悉搜索引擎的朋友一定对Lucene有耳闻,如果说百度对于我们的生活不可或缺,那么,Lucene对于做搜索引擎的攻城狮们来说是同样的必不可少。当然了,搜索引擎也会牵涉到一些非常酷炫的名词,诸如数据挖掘,深度学习,网络爬虫之类的。总之一句话,Lucene很牛逼,攻城狮们很喜欢。

尽管如此,Lucene仅仅也只是一个库,想要使用它,必须以java等开发语言来使用,并且Lucene非常复杂,通常适合对检索的相关知识很熟悉的大牛们来使用,对于想挤入高端搜索领域的小白来说,则充满了深深的无力感。

针对这种情况,Elastic公司使用java语言开发出了一款简单易用的非关系型数据库——Elasticsearch,她屏蔽掉了Lucene的复杂特性,提供简单的RESTful API,让Lucene的搜索功能变得非常简单易用。下面是一些Elasticsearch在我们生活中的应用:

  • 维基百科使用Elasticsearch提供全文搜索并高亮关键字,以及输入实时搜索和搜索纠错等搜索建议功能;

  • StackOverflow结合全文搜索与地理位置查询,以及more-like-this功能来找到相关问题和答案;

  • Github使用Elasticsearch检索1300亿行的代码

  • ……

Elasticsearch是一个分布式非关系型数据库,在使用之前,需要对她的一些重要概念有所了解,首先是索引、类型和文档的概念,这里和传统关系型数据库中的数据库、表和行进行类比,虽然严格意义上它们并不相同,但初学的时候可以采用这样的类比来增进理解。

然后是集群,节点和分片的概念:

  • 集群:集群由一系列节点组合而成,对于用户来说是透明的,在启动的时候具有相同集群名的节点会主动加入到这个集群中;

  • 节点:一个节点就是一个Elasticsearch的服务器,即一个运行着的Elasticsearch实例,默认自动生成名字,为了便于管理,最好自定义一下节点的名字;

  • 分片:当索引中存在大量文档时,由于内存、硬盘、CPU等方面能力的限制,可能导致应用无法快速地响应,在这种情况下,数据可以分为若干部分,每一部分就称为一个分片,每一个分片其实都是一个独立的Lucene索引,它们可以放置在不同的Elasticsearch服务中,因此数据可以在集群的节点中传播。当查询的索引分布在多个分片上时,Elasticsearch会把查询发送给每个相关的分片,并将结果合并在一起,而应用程序并不知道分片的存在。分片往往有副本,这是为了防止服务器出现故障而导致数据丢失。

“Hello World”版增删改查

Hello World程序是每一个码农入坑的起点,作为Elasticsearch入门,这里给出一个基于“hello world”版的Elasticsearch增删改查。

创建索引:

创建文档:

搜索文档:

更新文档:

删除文档:

第一次接触这些语句可能会有些陌生,不要怕,且听我细细道来,curl是利用URL语法在命令行下工作的开源传输工具,可以通过在Windows中安装cygwin来安装该工具,其实git bush工具默认安装了curl工具,所以安装了git bush工具的朋友可以直接在git bush中输入上面的指令。这里没有详细介绍Elasticsearch的安装,只要在网上下载一个Elasticsearch,直接运行就可以了,localhost表示本机主机,9200是Elasticsearch的默认HTTP请求端口号(如果是使用编程语言和Elasticsearch通信,则端口号默认为9300)。custom是索引名,external是类型名,1是ID号,用于文档标识。至于pretty,顾名思义就是格式化Elasticsearch返回的信息(实际上就是json字符串的格式化),使之便于阅读,实际的执行效果如下图所示(以创建索引为例):

这里返回true说明我们的创建成功了。-d 后面跟了一个json串,后面是一些具体的配置信息,里面放置的是语句的具体参数,比如创建文档语句中指明了该文档有一个字段name,它的值为John Doe;更新文档语句中的”doc”表示文档局部参数,该语句会将原来ID为1的文档的name字段修改为JaneDoe,并增加一个字段age,值为20。

多文档与批量化操作:

在实际使用中很多时候都需要同时操作多个文档对象,Elasticsearch提供了多文档与批量化操作的接口。

多文档:用一条指令执行多个文档请求,通过_mget指令来实现:

批量化:只发一个请求,在这个请求中执行多个操作:

结构化查询语句

在关系型数据库中,使用最多的是select查询语句,与之对应的,Elasticsearch使用最多的查询语句是_search,其支持两种类型的查询:简单字符串查询与结构化查询(DSL),简单字符串查询使用简单,但使用不够灵活,Elasticsearch官方比较推荐结构化查询,下面介绍结构化查询语句。

先给出一个不带任何查询条件的空查询实例:

这里在查询字符串后面加了“-d”,用于指定后面的查询体,查询体由一个json字符串构成,“query”是查询的类型,与之对应的是“filter”,两者主要的区别在于文档匹配的方式,“query”用于查询与查询条件“相同或相似”的文档,查询结果按照与查询条件的相似度进行降序排列,而“filter”用于“过滤式”的查询,仅仅匹配与查询条件完全一致的文档,但其速度一般快于“query”查询。“match_all”是在“query”之下的指令,用于匹配索引中的所有文档,在“query”和“filter”之下还有很多指令,现列举如下:

match子句:用于指定查询条件:

上面的address是字段名,而mill lane是匹配条件,值得注意的是该语句会匹配address字段包含“mill”或“lane”的文档,如果要匹配包含“mill lane”的文档则需要将match换成match_phrase。

返回特定的字段,类似于关系型数据库返回特定列内容的select语句,Elasticsearch也提供了类似的指令,使用_source指定特定的字段名:

排序子句:通过sort和order来指定,下面的语句指定根据account_number 字段的内容进行降序排列(升序排列只需将desc改为asc即可):

bool查询:顾名思义,bool查询就是表示查询条件中与或非关系的子句,与或非关系分别由must,should和must_not表示,下面给出与关系的示例:

上面的语句匹配address字段包含“mill”和“lane”的文档。

聚合:聚合提供了用户进行分组和数理统计的功能,和关系型数据库的groupby有些类似,但功能更为强大。使用agg指令进行实现:

上面的聚合语句表示按照state字段进行聚合,结果会列出state的所有不重复的值,并给出没一个值对应的文档数。值得注意的是:聚合支持在一个聚合之下进行再此聚合,即聚合嵌套。

映射

前面介绍了Elasticsearch的基本使用,从这里开始,将进入Elasticsearch数据类型方面的内容——映射。先看如下的三条查询语句:

这三条语句最后的结果会不会一样呢?如果不一样又会有什么差别呢?带着这个问题,我们进行下面的学习。

确切值VS全文文本:

Elasticsearch中包含的简单数据类型:

确切值表示该值是确定的,索引结果是“二进制”型的,要么匹配,要么不匹配,而文本值并非是“二进制”型的,对于文本值,我们不会去问文档是否匹配,而是关心文档的对于查询条件的匹配程度,上表中String类型既可以代表文本值又可以表示确切值,而Whole number,Floating point,Boolean和Date类型都只能表示确切值,在插入文档时,如果没有事先对文档的各个字段指定类型,Elasticsearch会对写入各字段的值进行判断,进而给各个字段分批合适的数据类型。该过程即为映射过程,查看某一类型内各个字段的指令如下:

上面的指令通过_mapping指令查看employee索引的net类型各字段的数据类型。也可以给索引的具体类型指定类型,前面提到过String类型既可以作为全文文本匹配也可以作为确切值进行匹配,这取决于对映射额参数index的设置,String类型默认是全文文本匹配:

指定映射类型的语句示例如下:

上面的语句将football-type指定为String类型,并且该String类型作为确切值使用。

分析:

分析是Elasticsearch中一个非常重要的概念,其根据不同的分析器对文本进行处理,最终可能得到不同的查询结果。对于字符串类型的字段,可以使用analyzer参数来指定该字段的分析器,如下所示:

分析的大致流程分为表征化文本块和词的标准化两个过程,常用的分析器有标准分析器,简单分析器,空格分析器和语言分析器等。

分析的具体流程如下所示,图中结果显示的是标准的分析器的结果,另外三类分析器的结果如下所示:

简单分析器:exact, value,full,text

空格分析器:Exact, value,full_text

语言分析器:exact,value,full,text

分析流程:

回到前面的问题,使用标准分析器对前面的字符串进行分词,得到三条语句的分词结果以及查询结果如下:

因此三条查询语句的查询结果是完全不一样的,与数据类型和分析器有关。

代码情节

这一部分以java语言为例,讲述使用java对Elasticsearch进行简单操作。使用代码操作Elasticsearch主要有以下步骤:

  • 客户端获取及其设置

官方提供两类客户端与Elasticsearch进行交互:

Client类型:

TransClient类型:

注:前面提到过程序与elasticsearch交互的默认端口为9300

  • 数据库增删改查

生成索引:

查询:

读取查询结果:

删除文档:

综合案例展示

场景:分页查询是数据库的重要内容,在Elasticsearch中分页查询主要采用from&size语句完成,但是由于深分页带来的资源消耗的原因,from&size语句仅支持1W条数据之内的分页查询,超过这个数量的from&size语句将会抛出异常,为了解决这个问题,Elasticsearch提供了一个滚动遍历数据的方案,每滚动一次就会返回指定大小的数据条目,第一次滚动之后会返回一个scrollID,在指定时间内使用返回的scrollID再次滚动会返回下一批数据……直到数据返回为空,表示滚动结束。

下面的小程序演示了采用scroll方式来查询大数据量下的最后100条数据,给每个都有一个标识ID,先设置scroll的size为10000,也即按照每次滚动10000条数据来浏览数据,缓存每个10000条数据的起始ID,数据遍历完成后,再按照实际的需求计算出需要的ID返回,最后将该ID范围作为查询条件,返回对应的数据,具体代码如下:

小结

这篇文章简单介绍了Elasticsearch的使用以及开发。麻雀虽小五脏俱全,文章虽然只涵盖了ELasticsearch内容的小部分,但是贯穿了从使用到开发的整个流程,希望读者能够藉此入门,如果能达到抛砖引玉之奇效,也不失为功德一件,如果还想深入理解和学习Elasticsearch的同学,可以上Elasticsearch的官网看看:

Elasticsearch使用手册:

https://www.elastic.co/guide/en/elasticsearch/reference/current/getting-started.html

Elasticsearch java开发文档:

https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/java-api.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值