Elasticsearch 检索

说到查询,那么索引也是一个绕不开的话题,能够说,没有索引就没有检索,先来看一个示意图 工具

 

左边是索引过程,右边是检索过程。关键的步骤是分词过程,我用等号表示这两个过程同样,并且,必须同样,这个等号并非模糊的流程的相同,并且必须是逻辑也相同。 简单来说,采用的分词器和分词流程须要同样,不然,颇有可能填进去的文档,搜不出来。网站

 

本篇重点在如何用JAVA API实现查询上,就不深刻说索引的过程了,之后有时间再深刻。ui

 

对于查询,有两个基础的类型,Match查询,和Term查询。这也是跟索引过程相关的。刚开始接触的索引,我就想,若是把全部的内容都作搜索,那么一是须要创建很是多的索引,再一个是要保存特别多的原始数据,随着了解的加深,我发现并非这样的。spa

 

在进行索引的时候,先新建文档,在往文档中添加字段时,有Index设置和Store设置。index设置就是是否要对这个字段用分词器进行分词。举个例子,有个字段A,内容为中华人民共和国国歌,以中文分词器IK为例,若是不进行分词,那么往索引中插入的时候,直接用一个词“中华人民共和国国歌”。若是A字段设置为进行索引,那么IK分词器就会将“中华人民共和国国歌”分解为“中华人民共和国”和“国歌”两个词,往索引中添加的时候,是两个记录。翻译

对于Store选项,若是选择Yes,就是存储这个字段的原始值,对于字段A来讲,就是保存“中华人民共和国国歌”,这样,在检索以后,若是查询到字段A,能够返回A的原始值。若是选择Store为No,而且设置为A进行索引,那么A字段的原始值就不可知了。索引中只存在“中华人民共和国”和“国歌”,并不存在“中华人民共和国国歌”。你能够检索到字段A,可是A的原始值是什么,ES就不知道了,须要去原始的数据源中找出来。blog

 

这两个设置是十分关键的,好比id,基本不须要进行索引分词,直接存储就是了,并且,你查询的时候,也确定不须要对id进行分词,因此,这个就是term查询的用处。term就是词的意思,Lucene中将分词以后的结果成为Term,因此,像id这样的不须要分词的,直接就跟通过分词步骤的词同样了,能够用这个词直接去倒排索引中查询了。因此,Term查看的字段,最好设置为Index为No,不然,通常搜不到。排序

 

Store选项能够有效减少ES的存储规模,你想一想,你用百度去搜索,确定都会到目标的网页,而不是在百度里面浏览,百度只要告诉你,你想去的网页的URL就能够了。因此,在进行索引的时候,像整个网页的内容,并非须要的,须要的是对整个网页进行分词以后产生的词,而后就能够将原始的网页文本丢弃了。固然,百度也存储了这个内容的,百度快照就是。索引

 

Match查询就是须要对搜索的关键词进行分词,而后将分词的结果拿到倒排索引里面去检索,检索以后,再对这个结果进行相关性分词,而后排序进行输出。能够看出,Match查询要比Term查询多了至少两步,分词和相关性计算。文档

 

好比说咱们要索引一个网页,网页有一些基本meta信息。那么首先,咱们把网页给抓取到,分析网页里面的内容。网页的meta信息比较关键,咱们提取出来,准备构建一个文档,网页的关键字,meta信息,更新时间等这些均可以成为io

 

除了这两类最主要的,还有范围查询,bool查询等,这些都是跟SQL同样的组合查询。

SearchRequestBuilder是最主要的查询方法,QueryBuilders提供了多种构造查询语句的方式。Kibana里面集成的DevTools是使用Query DSL很是方便的一个工具。

 

SearchRequestBuilder searchRequestBuilder = client.prepareSearch((String[])tempIndices.toArray(new String[tempIndices.size()]));

searchRequestBuilder.setTypes(typesName);

searchRequestBuilder.setQuery(qb);

searchRequestBuilder.addStoredField(field);//设置返回的字段,注意,这里返回的必须是Stored是Yes的。

searchRequestBuilder.setSize(size);

searchRequestBuilder.setFrom(from);

SearchResponse searchResponse = requestBuilder.execute().actionGet();

 

那么如何构造Query?这就是如何从咱们的查询转化成ES的Query DSL,有关kibana使用的就是DSL,有关DSL的介绍,查看elastic.co或者网站翻译的Elasticsearch权威指南。尽可能仍是参考elastic.co的,由于ES更新比较快,最靠谱的仍是上面的介绍。

 

QueryBuilders.rangeQuery();//范围查询

 

QueryBuilders.geoDistanceRangeQuery("fieldName", new GeoPoint(Long.parseLong("经度"), Long.parseLong("纬度")))

.from( "1km")

.to("2km")

.includeLower(true)

.includeUpper(true);//地理位置插叙

 

QueryBuilders.termQuery("field", "keyword");//term查看

 

QueryBuilders.matchQuery("field", "keyword");//match查看

 

另外,可使用QueryBuilders.boolQuery();将上面的query联合起来,链接的关系有Must(等同于SQL的AND),MustNot(等同于SQL的NOT),SHOULD(等同于OR)

 

基本上,以上都是初步的查询API。

相关文章
相关标签/搜索