• Elasticsearch 检索


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

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

     

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

     

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

     

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

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

    这两个设置是十分关键的,比如id,基本不需要进行索引分词,直接存储就是了,而且,你查询的时候,也肯定不需要对id进行分词,所以,这个就是term查询的用处。term就是词的意思,Lucene中将分词之后的结果成为Term,所以,像id这样的不需要分词的,直接就跟经过分词步骤的词一样了,可以用这个词直接去倒排索引中查询了。所以,Term查看的字段,最好设置为Index为No,否则,一般搜不到。

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

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

     

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

    除了这两类最主要的,还有范围查询,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。

  • 相关阅读:
    服务部署 RPC vs RESTful
    模拟浏览器之从 Selenium 到splinter
    windows程序设计 vs2012 新建win32项目
    ubuntu python 安装numpy,scipy.pandas.....
    vmvare 将主机的文件复制到虚拟机系统中 安装WMware tools
    ubuntu 修改root密码
    python 定义类 简单使用
    python 定义函数 两个文件调用函数
    python 定义函数 调用函数
    python windows 安装gensim
  • 原文地址:https://www.cnblogs.com/kamong/p/6104026.html
Copyright © 2020-2023  润新知