JavaAPI实现Elasticsearch5.5.2一些常用的搜索

来源:互联网 发布:mac安装win10镜像 编辑:程序博客网 时间:2024/06/15 22:36

前段时间学了elasticsearch的搜索,但是一直都是用elasticsearch原生的命令完成一些搜索,但是因为本人一直在搞java服务端开发,所以就根据elasticsearch官方的API和网上的一些资料对一些常用的搜索通过java来实现了,下边写的一些比较常用也是很基础的搜索,我使用的elasticsearch版本是5.5.2。

一、首先构建elasticsearch客户端

因为我是基于一个SpringBoot进行的完成的,这里使用的是TransportClient,在项目给它定义了一个配置类,那么我们需要他的时候,直接进行注入就可以了。

@Configurationpublic class MyConfig {    @Bean    public TransportClient client() throws UnknownHostException{        //配置节点        InetSocketTransportAddress node = new InetSocketTransportAddress(                InetAddress.getByName("localhost"),                9300        );        //配置settiong        Settings settings = Settings.builder()                .put("cluster.name", "my-application")                .build();        TransportClient client = new PreBuiltTransportClient(settings);        client.addTransportAddress(node);        return client;    }
二、javaAPI搜索语句简单介绍

使用java进行elasticsearch搜索的时候,他的api算是很好使用的,基本上我们做的大多数的搜索,整体java语句都是差不多的,首先我先把官方一个搜索语句放到这里,做一个简单的注释

SearchResponse response = client.prepareSearch("index1", "index2")//index1,index2指的是我们需要查询的索引,相当于数据库的名称        .setTypes("type1", "type2")//type1,type2是我们需要查询的type,相当于数据库的表名字        .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)//指的是我们需要采取的搜索方式        .setQuery(QueryBuilders.termQuery("multi", "test"))                 // 主要是构建我们的查询条件        .setPostFilter(QueryBuilders.rangeQuery("age").from(12).to(18))     // 用于查询的过滤        .setFrom(0).setSize(60)//这里就是一个分页功能.setExplain(true)        .get();
其实,我们在进行搜索查询的时候,只需要关心QueryBuilders的构建和fiter的过滤就可以了。

三、elasticsearch进行搜索javaAPI的使用

3.1简单搜索

这个搜索,我会把所有的java语句,写出来,供大家进行参考,其他的搜索我直接写出QueryBuilers的构建

3.1.1.termQuery等值搜索

我们在数据库中进行查询的时候,sql:select sales from tvs where brand = ‘小米’,那么在elasticsearch中的javaapi怎么写呢?这里我们用到一个termQuery,他相当于sql语句中的“=”,使用这个搜索一般是对索引中keyword的mapping进行等值搜索,例如

//确定搜索的index和typeSearchRequestBuilder requestBuilder = client.prepareSearch("tvs").setTypes("sales");//构建query语句TermQueryBuilder termQuery = QueryBuilders.termQuery("brand", "小米");//我们可以将我们构建好的查询打印出来System.out.println(termQuery);//进行搜索SearchResponse response = requestBuilder.setSearchType(SearchType.DFS_QUERY_THEN_FETCH).setQuery(termQuery).setFrom(0).setSize(10).execute().actionGet();//查看搜索结果for(SearchHit hit:response.getHits()){Map<String, Object> source = hit.getSource();System.out.println(source);}
3.1.2 matchQuery 匹配查询

matchQuery可以简单理解为mysql中的like,但是我不知道我这么理解对不对,因为在elasticsearch中使用matchQuery查询时,他会对查询的field进行分词,打个比方,我们搜索"联想笔记本电脑",他可能会将他拆分为:“联想”,“电脑”,“联想电脑”,那么如果一个filed中包括 联想 两个字就可以被搜出来。当然我们进行查询的这个field的mapping必须是text类型。(如果是中文分词的话,还需要配置中文分词器),他的查询语句和上边基本相似

MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("title", "联想电脑");//title指定field
3.1.3matchAllQuery 查询所用

查询指定index和type中的所用记录,相当于sql:select * from sales 

 MatchAllQueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();
3.1.4 matchPhraseQuery短语搜索
MatchPhraseQueryBuilder matchPhraseQuery = QueryBuilders.matchPhraseQuery("title", "联想电脑");
3.1.5 prefixQuery前缀搜索

如我我们需要查询的title中有“大话西游电影”,“大话西游小说”,使用prefixQuery查询“大话西游”,那么那两条数据就会出来

PrefixQueryBuilder prefixQuery = QueryBuilders.prefixQuery("title", "大话西游");
3.1.6 disMaxQuery
disMaxQuery适用于多个field的进行搜索,我们在多个field搜索时候,可能会遇到多个field匹配到了更多的词会在前面,而一个field匹配了更多的词就会排名靠后。disMax就是解决这个问题,dismax使搜索到的结果,应该是某一个field中匹配到了尽可能多的关键词,被排在前面;而不是尽可能多的field匹配到了少数的关键词,排在了前面

DisMaxQueryBuilder disMaxQueryBuilder = QueryBuilders.disMaxQuery().add(QueryBuilders.matchQuery("title", "elastic")).add(QueryBuilders.matchQuery("content", "elastic search"));

对于一些简单的搜索,我先整理到这里,其实还有好多。。。大家可以查询javaAPI,这里就不一一列出来。

3.2多条件搜索

多条件搜索也就是sql语句里面的多个条件搜索

3.2.1boolQuery 组合查询条件

boolQuery用来将搜索的条件进行组合,即将多个组合条件组合在一起,常用的几种组合方式有must、should、mustNot,我们拿下面对应的sql语句举例子(同上面一样,我们只需要将构建好的QueryBuilder放到里面就可以了,参考3.1.1)

sql:select * from sales where brand = '小米' and color='红色',通过bool将两个查询条件组合,must相当于sql中的= 必须匹配的意思

BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();boolQuery.must(QueryBuilders.termQuery("brand", "小米")).must(QueryBuilders.termQuery("color", "红色"));
sql:select * from sales where brand = '小米' or color='红色';使用should相当于sql语句中的or
BoolQueryBuilder boolQuery2 = QueryBuilders.boolQuery();boolQuery2.should(QueryBuilders.termQuery("brand", "小米")).should(QueryBuilders.termQuery("color", "红色"));
//sql:select * from sales where brand = '小米' and color != '红色'  mustNot相当于!= 必须不匹配
BoolQueryBuilder boolQuery3 = QueryBuilders.boolQuery();boolQuery2.must(QueryBuilders.termQuery("brand", "小米")).mustNot(QueryBuilders.termQuery("color", "红色"));
sql:select * from sales where (brand = '小米' or color = '红色') and brand != '长虹'
BoolQueryBuilder boolQuery4 = QueryBuilders.boolQuery();BoolQueryBuilder boolQuery5 = QueryBuilders.boolQuery();boolQuery5.should(QueryBuilders.termQuery("brand", "小米")).should(QueryBuilders.termQuery("color", "红色"));boolQuery4.must(boolQuery5).mustNot(QueryBuilders.termQuery("brand", "长虹"));

3.2.2Filter 过滤

filter用来对搜索条件进行过滤,我们在sql语句中的>,<等等都可以用它来实现,我们同样用例子来说明

sql:select * from sales where price > 1200 and price < 1800

RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price").gt("1200");
sql:select * from sales where price > 1200 and price < 1800
RangeQueryBuilder rangeQueryBuilder1 = QueryBuilders.rangeQuery("price").from(1200).to(1800);
sql:select * from sales where brand = ‘小米’ and price > 1200
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); boolQuery.must(QueryBuilders.termQuery("brand", "小米")); boolQuery.must(QueryBuilders.rangeQuery("price").gt("1200"));
3.2.3Sort 排序

使用addSort对指定的field进行排序,我们可以选择是DESC还是ASE,如果不写默认是倒叙

SearchResponse response =  client.prepareSearch("tvs") .setTypes("sales") .setQuery(QueryBuilders.matchAllQuery()) .addSort("price", SortOrder.DESC) .setFrom(0) .setSize(10) .execute() .actionGet();
3.2.4分页

分页的语句很简单,我在上边的语句中都已经提到了

.setFrom(1).setSize(10)//表示第1页开始,一页有10条记录


这篇文章主要是对elasticsearch的一些搜索,通过javaAPI来实现了,我会在下面的文章中,整理出elasticsearch其他的一些功能,比如搜索结果高亮显示、搜索建议、聚合分析等等,持续更新中....如果我在上面的文章中,有哪些地方不对,请大家及时纠正,感激不尽!