目录html
优势:高效,准确,分词
全文检索容许用户输入一些关键字,从数据层中查找到所须要的信息java
lucene是一个是一个开源的全文检索引擎库,Apache基金会赞助项目.不管在开源仍是专有领域,Lucene能够被认为是迄今为止最早进、性能最好的、功能最全的搜索引擎库(《Elastic Search 权威指南》)。lucene有不少优势,包括:它的文本分析器能够定制,检索文件存储方式能够定制,查询引擎也有不一样的可选方案.此外,它提供一套很是强大的API接口,使客户用起来很方便.算法
lucene是一个很是强大的全文检索引擎库,可是遗憾的是,它是一个库,想要使用它,你必须使用Java来做为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene很是复杂,你须要深刻了解检索的相关知识来理解它是如何工做的。数据库
Elasticsearch也使用Java开发并使用Lucene做为其核心来实现全部索引和搜索的功能,可是它的目的是经过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。json
ES的安装很简单,即装即用.去官网下载ES下载地址,在任何配置了java运行环境的电脑上后将压缩文件解压缩便可.
解压后进入解压下的bin文件夹,启动elasticserach.bat(windows系统),以下:
启动后进入cmd窗口,以下图所示即成功启动:
而后咱们打开浏览器访问如下ES,输入http:localhost:9200,以下即为成功运行:
windows
ES是数据存储是面向文档的,数据的存储形式是以对象的形式(JSON)来存储的,而不是像关系型数据库同样把数据抽象一行行记录去适应数据库.同时在存储的时候,ES还会索引每条数据内容使得每条内容能够被搜索.
ES存储的相关概念与传统关系型数据库的对比:
其中的fields(字段)就至关于关系型数据库的列;多个字段组成一个Document(文档)至关于关系型数据库的行(一条数据);相同类型的Documents组成一个type(类型),至关于关系型数据库的一张数据表;而多个types就会组成一个index(索引),至关于关系型数据的数据库.关系对应以下:api
Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch -> Indices -> Types -> Documents -> Fields数组
ES对提供的REST ful接口,任何对数据的操做和查询均可以经过想ES发送HTTP请求来完成.关于RESTful协议的相关知识能够参照一下RESTful API 设计指南,了解一下RESTful协议能共更容易理解ES提供的接口.
如今咱们要创建一个因此,按照ES提供的RESTful接口,咱们应该对ES发一个PUT请求,以下:浏览器
须要注意的是index名字里的字母都必须是小写.
若是成功,咱们会获取以下的返回结果:
{ "acknowledged": true }
而后咱们再向ES发送GET请求,来获取咱们刚刚建立的testindex的属性:
结果以下:
{ "testindex": { "aliases": {}, "mappings": {}, "settings": { "index": { "creation_date": "1465748163064", "uuid": "uYyeZC_bQ1Olwe8lDrqXaw", "number_of_replicas": "1", "number_of_shards": "5", "version": { "created": "2030399" } } }, "warmers": {} } }
相关的tpye,document最简单的增删查改也均可以经过PUT GET POST DELET 几个经常使用的请求来完成,这里就不作详细的介绍了,详细的能够查看ElasticSearch权威指南中文版了解一下.
mapping能够理解为描述index/type以及field的元数据,经过mapping咱们能够来设置index/type/field.
单独的生成或者更新type的mappiing
{ "properties": { "activateTiem": { "type": "date", "format": "yyyy-MM-dd" }, "title": { "type": "string", "boost": 10, "store": true, "analyzer": "ik" } } }
参考文档:更新mapping
一般咱们须要在构建mapping的时候来设置一些经常使用的属性,主要是包括字段的类型,是否被分词,分词使用的分词器,分词时候本身所占的比重等,以下:
- type:类型,包括date,string,boolean,integer等,跟经常使用的类型跟java很类似,同时也有array类型能够直接存储数组.
其他的更多的类型能够参考官方文档mapping
ES为了可以更好的进行查询,在保存数据以前,都会对数据进行索引(动词),那么在这个因此过程里面,ES都作了什么?
ES会对文档进行一系列的操做和处理,是他们可以更容易被搜索.它包括以下的几个过程:
字符过滤器的主要工做室对原始数据的特殊字符进行过滤和处理,好比去除掉文档中的html标签,把&变成单词"and"等等
所谓的分词器就是指某种算法,这个算法会按照本身的对文档(通过字符过滤器处理过的文档)进行处理,提取若干的单词,这些被提取出来的单词就成为词元(Token),顾名思义,这些词元已是最小的不能分割了.
标记过滤(token filters)会对词元(Token)进行进一步的处理,处理细节包括一些将单词的大写变成小写、去除英语中的连词或者介词(to,for,of等)、去除汉语中的语气词等、进一步保证最后剩下的单词都是有明确的天然语义的词,这些剩下的单词就被称做词(term)
到此整个文档分析阶段就结束了
Elasticsearch使用一种叫作倒排索引(inverted index)的结构来作快速的全文搜索。倒排索引由在文档中出现的惟一的单词列表,以及对于每一个单词在文档中的位置组成。
分词结束后,es会根据分词的结果词(term)构建出一个倒序索引用于快速查询.
在索引阶段es作的另外一件事就是计算不一样词(term)在不一样文档中的相关度评分,这个评分会用在以后查询时候的查询结果的排序上,默认的会将相关度较高的文档排在最前面
当咱们须要查询的时候,最简单的,咱们能够向ES发送一个get请求,构造一个查询的url,以下
默认的,会ES会发挥my_index下的全部数据,若是数据过多ES会自动进行分页处理显示一部分数据(默认是10个).会返回以下形式的结果:
{ "took": 62, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1, "max_score": 1, "hits": [ { "_index": "my_index", "_type": "my_type", "_id": "1", "_score": 1, "_source": { "title": "Some short title", "date": "2015-01-01", "content": "A very long content field..." } } ] } }
若是咱们须要分页功能,就须要在get请求的url中加入size和from俩个参数,size表示分页大小,from表示开始位置,以下:
若是须要模糊查询,能够在URL参数中附加一个q(query的意思)参数,以下:
GET http://localhost:9200/my_index/_search?q=title:Some
意思是查询my_index下title中包含"Some"的数据.
经过URL参数控制,咱们只能进行一下简单的查询,可是在实际过程当中,咱们通产的查询条件都要更加复杂,这时候咱们就须要使用另外一种适用于复杂查询的方式--结构体查询.
按照rest ful协议,咱们也是应该想ES发送GET请求来获取ES中的数据,可是在平常开发中,不少地方都不容许在GET请求上附加body数据,所以ES中咱们也能够经过POST来获取ES中的数据.发送POST请求的时候,除了请求方式以外,URL和数据体body都跟GET的彻底相同(如下都以POST请求为例)
{ "query": { "bool": { "must": [ { "match": { "title": "Search" }}, { "match": { "content": "Elasticsearch" }} ], "filter": [ { "term": { "status": "published" }} ] } } }
上面的body的大意是要搜索title中即包含"search"而且content中包含"elasticsearch",同时status为"published"数据.关于query有专门的queryDSL来规定query的形式,在后面文档中会介绍.
{ "from" : 0, "size" : 10, "query" : { "term" : { "user" : "kimchy" } } }
{ "sort" : [ { "post_date" : {"order" : "asc"}}, { "price" : {"order" : "asc"}} ], "query" : { "term" : { "user" : "kimchy" } } }
如上,sort会优先按照post_date进行正序排序,当post_date相同的时候在按照price进行正序排序.特别的在平常的查询中,查询结果一般都会有相关的_scroe评分,默认的,ES会按照_score对搜索结果进行性倒叙排序,是的相关度最高的文档在最前方显示.
{ "query":{ "match":{"title":"some"} } }
查询的返回结果默认的会包含全部保存的字段:
{ "_index": "my_index", "_type": "my_type", "_id": "1", "_score": 0.15342641, "_source": { "title": "Some short title", "date": "2015-01-01", "content": "A very long content field..." } }
当咱们使用fields的时候,body以下:
{ "fields":["title"], "query":{ "match":{"title":"some"} } }
返回结果的数据部分指挥显示title字段:
{ "_index": "my_index", "_type": "my_type", "_id": "1", "_score": 0.15342641, "fields": { "title": [ "Some short title" ] } }
{ "query":{ "match":{"title":"some"} }, "highlight" : { "pre_tags" : ["<b>"], //设置高亮的前 后html标签 "post_tags" : ["</b>"], "fields" : { "title" : {} } } }
在返回的数据部分,咱们会获得高亮的字段,以下
{ "_index": "my_index", "_type": "my_type", "_id": "1", "_score": 0.15342641, "_source": { "title": "Some short title", "date": "2015-01-01", "content": "A very long content field..." }, "highlight": { "title": [ "<b>Some</b> short title" //这里是高亮显示的关键字 ] } }
ES的主要任务是经过全文搜索引擎进行全文搜索,在ES提供的接口中,这部分任务主要由请求体中的query部门来完成的.而query DSL就是来解释query的用法.