上一篇blog详细介绍了lucene的基本概念和使用,本篇blog介绍的就是其工业级的应用ElasticSearch。也就是系列文章的主题。Elaticsearch,简称为es, es是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB[1024TB]级别的数据。es也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单:
- Elasticsearch 自身带有分布式协调管理功能
- Elasticsearch 仅支持json文件格式
- Elasticsearch 本身更注重于核心功能,高级功能多有第三方插件提供
- Elasticsearch处理实时搜索应用时效率很高
以上的所有特点都标注了Elasticsearch实质上是一款高效的分布式的全文搜索引擎
ElasticSearch核心概念
ElasticSearch是一个面向文档的搜索引擎,这意味着它可以存储整个对象或文档(document)。然而它不仅
仅是存储,还会索引(index)每个文档的内容使之可以被搜索。在Elasticsearch中,你可以对文档(而非成行成列的数据)进行索引、搜索、排序、过滤。Elasticsearch比传统关系型数据库如下:
类别 | 库 | 表 | 行 | 列 |
关系型数据库 | Databases | Tables | Rows | Columns |
ElasticSearch | Indices | Types | Docements | Fields |
Elasticsearch具备接近实时 NRT,Elasticsearch是一个接近实时的搜索平台。这意味着,从索引一个文档直到这个文档能够被搜索到有一个轻微的延迟(通常是1秒以内)
级别 | 概念 | 对应lucene概念 |
索引 index | 一个索引就是一个拥有几分相似特征的文档的集合。比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字来标识(必须全部是小写字母),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。在一个集群中,可以定义任意多的索引。实际上对应于**** | 索引 |
类型 type | 在一个索引中,你可以定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类/分区,其语义完全由你来定。通常,会为具有一组共同字段的文档定义一个类型。比如说,我们假设你运营一个博客平台并且将你所有的数据存储到一个索引中。在这个索引中,你可以为用户数据定义一个类型,为博客数据定义另一个类型,当然,也可以为评论数据定义另一个类型。 | |
字段Field | 相当于是数据表的字段,对文档数据根据不同属性进行的分类标识 | 字段域 |
映射 mapping | mapping是处理数据的方式和规则方面做一些限制,如某个字段的数据类型、默认值、分析器、是否被索引等等,这些都是映射里面可以设置的,其它就是处理es里面数据的一些使用规则设置也叫做映射,按着最优规则处理数据对性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能对性能更好。一般每个type都需要一个mapping信息 | 字段域的一些属性配置 |
文档 document | 一个文档是一个可被索引的基础信息单元。比如,你可以拥有某一个客户的文档,某一个产品的一个文档,当然,也可以拥有某个订单的一个文档。文档以JSON(Javascript Object Notation)格式来表示,而JSON是一个到处存在的互联网数据交互格式。在一个index/type里面,你可以存储任意多的文档。注意,尽管一个文档,物理上存在于一个索引之中,文档必须被索引/赋予一个索引的type | 文档 |
ElasticSearch环境配置
ElasticSearch的官方地址可以直接下载到软件,本质上ElasticSearch就是一个服务器,服务器上存放了索引数据,看项目结构也可以看出,实质上是一个tomcat的典型服务器目录:
修改elasticsearch配置文件:config/elasticsearch.yml,增加以下两句命令:
http.cors.enabled: true http.cors.allow-origin: "*"
此步为允许elasticsearch跨越访问,如果不安装后面的elasticsearch-head是可以不修改,直接启动。 可以直接使用windows下的bat命令启动起来,启动完成后弹出弹窗,可以看出,也是一个服务器风格的:
其中9300为tcp的通讯接口【代码接口调用使用】,9200为RestFul风格通讯接口【Http调用访问】,可以尝试用restful风格访问,可以看到如下基本信息:
我们可以通过安装ElasticSearch的head插件,完成图形化界面的效果,完成索引数据的查看,下载服务器的图形化界面【类似于mysql数据库下载的navicat】,head将grunt安装为全局命令 ,Grunt是基于Node.js的项目构建工具,在浏览器中运行,是一款浏览器插件,首先按照npm,安装完npm后使用命令安装Grunt,在cmd控制台中输入如下执行命令:npm install -g grunt-cli
进入elasticsearch-head-master目录启动head,在命令提示符下输入命令:npm install
和grunt server
可以看到head已经启动完成了,之前之所以要求跨越关于跨越的介绍访问,是因为head的域名是:http://localhost:9100/,而es的域名是http://localhost:9200/,我们在head向es发送请求:
这种行为实际上就是向es发送http请求来创建索引,例如我们点击创建索引,可以看到实际上是一次向es的restful请求,看请求地址就可以看的出来,参数是默认的5个分片和一个副本。
ElasticSearch客户端操作
包括索引的维护和数据的维护两部分内容。
索引的维护
既然可以看的出head的操作实际上就是一个请求的发布,实际上我们可以自己直接发http请求即可,实际开发中,主要有三种方式可以作为elasticsearch服务的客户端:
- 第一种,elasticsearch-head插件:其本质和第二种一样,也是通过http请求实现的
- 第二种,使用elasticsearch提供的Restful接口直接访问,最常用的方式就是使用postman,postman的使用方式已经有篇blog介绍了Postman最佳实践,这里就不再赘述,我们直接看如何用postman来操作es的增删改查。
- 第三种,使用elasticsearch提供的API进行访问,这种就需要引入相关的jar包,然后用tcp的方式请求。
这部分主要介绍如何通过http请求实现,通过java去操作的方式下篇blog介绍。
创建索引index和映射mapping
需要注意,ES中支持如下几种数据类型:
- text 用于索引全文值的字段,例如电子邮件正文或产品说明。这些字段是被分词的,它们通过分词器传递 ,以在被索引之前将字符串转换为单个术语的列表。分析过程允许Elasticsearch搜索单个单词中每个完整的文本字段。文本字段不用于排序,很少用于聚合。
- keyword 用于索引结构化内容的字段,例如电子邮件地址,主机名,状态代码,邮政编码或标签。它们通常用于过滤,排序,和聚合。keyword字段只能按其确切值进行搜索
然后再去head看,是一样的效果,创建成功,不传任何分片参数,默认5片和一个复制。
创建索引后设置Mapping
在tmlblog2中我们刚刚直接创建了索引,但是没有创建映射mapping:
这个时候我们补充创建一个mapping:
创建完成后可以看到tmlblog2已经有hello的mapping信息了:
删除索引index
直接删除tmlblog这个索引:
可以看到该索引已经被删除不存在了:
文档的维护
上一部分介绍了如何对索引进行维护,这部分介绍下如何对文档进行维护,也就是索引里的数据。
创建文档
创文档很简单,就是在具体的type下请求一个文档的数据:
可以在head里看到一条文档记录已经入库了:
修改文档
和创建文档一样,定位到要修改的文档,body里用新数据即可:
查看修改的效果:
删除文档
直接定位到对应的文档,执行删除请求:
从head里可以查看到:
查询文档
通过id查询、通过term查询、通过queryString查询。
通过id查询
通过Get方法,使用id查询定位到文档可以直接获取该文档信息:
通过term查询
要查询的数据列表如下:
查询tml关键词,命中的数据如下:
通过queryString查询
在命中的域上先分析后依据关键词检索。
可以依据得分拿到一个检索列表
IK分词器的使用
因为服务器三个字在标准分词器下会被分为服、务、器,所以我们在term查询的时候检索服务的时候检索不到数据,因为没有服务这个分词,和lucene中学到的一样,我们需要使用IK分词器。
搜索服可以命中数据。
那么我们第一步还是安装IK,直接将IK的包保存到es的plugins里即可
重启es即可加载ik分词器:
IK提供了两个分词算法ik_smart 和 ik_max_word,其中 ik_smart 为最少切分,ik_max_word为最细粒度划分
{ "mappings": { "article": { "properties": { "id": { "type": "long", "store": true, "index":"not_analyzed" }, "title": { "type": "text", "store": true, "index":"analyzed", "analyzer":"ik_max_word" }, "content": { "type": "text", "store": true, "index":"analyzed", "analyzer":"ik_max_word" } } } } }
最小切分
如果是最小切分那么不切分到单字,这样querstring搜【服务】就不再能搜到了,因为querstring切分的关键词不包含,term搜【服务器】就可以搜到了。核心是搜索的内容是如何被切分的。
最大切分
最大切分的情况下,有可能被单字切分,粒度更细一些。此时term搜【服务】就可以搜到了
搜【服】搜不到了
搜【服务】可以搜到了
本篇blog介绍了ES的基本概念,基本操作和使用,以及IK分词器的引入和使用,下篇blog正式介绍其分布式集群的使用。