`
shuminghuang
  • 浏览: 51831 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java Client调用ElasticSearch做全文搜索代码示例

阅读更多

目前在做基于ElasticSearch的搜索实现,采用ElasticSearch提供的Java API实现,用TransportClient连接到ES的Cluster。

根据经验,一个搜索请求应该走这样的流程:

 

  1. Analyzer分析Query Term
  2. 根据Analyzer的结果构建TermQuery
  3. 发送Query请求给ES
  4. 处理返回结果

 

想找一段Sample Code,可是一直没找到ES里合适的Analyzer类,很奇怪为什么直接发JSON请求很简单的事,Java处理起来这么复杂(用JSON请求见:http://www.elasticsearch.org/guide/reference/query-dsl/query-string-query.html)。

 

静态在StackOverFlow的一个问题里无意看到了这个类:QueryStringQueryBuilder,一切问题迎刃而解了

 

代码解析

1 创建客户端

 

Settings settings = ImmutableSettings.settingsBuilder()
                .put("client.transport.sniff", true)
                .put("client", true)
                .put("data",false)
                .put("clusterName","elasticsearch")
                .build();

client = new TransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(hostName, 9300));

 

2 创建StringQuery对象:

 

QueryStringQueryBuilder = new QueryStringQueryBuilder(parameters.getQueryTerm());
queryStringBuilder.useDisMax(true);
			 queryStringBuilder.field("title",160);
			 queryStringBuilder.field("desc",1);

 

3 构建SearchRequest

 

SearchRequestBuilder builder= client.prepareSearch("indexName")
				.setTypes("collectionName")
				.setSearchType(SearchType.DEFAULT)
				.setFrom(parameters.getStart())
				.setSize(parameters.getCount());

builder.setQuery(queryStringBuilder);
 

这样,一个基本ElasticSearch请求就构建成功了。

 

Query 还是 Filter

以前一直弄不清楚为什么Filter也干一些Query可以做的事情,比如查询的附件条件是分类值为”1“,用TermQuery可是实现,用TermFilter也可以实现,为什么有重复的功能。

根据这里(http://es-cn.medcl.net/guide/reference/query-dsl/),可以看出,Filter最大的好处是可以实现缓存,并且不需要计算得分。

 

完善后的搜索

根据上面的结论,重新把搜索条件里的其他限定条件用Filter实现,代替掉原来的Query实现:

 

FilterBuilder categoryFilterBuilder = FilterBuilders.termFilter("categoryId", parameters.getCategoryId());
String[] ids = new String[parameters.getTypeIds().size()];
			parameters.getTypeIds().toArray(ids);
			FilterBuilder inFilter = FilterBuilders.inFilter("typeId", ids);

builder.setFilter(filterBuilder);
 

最后执行搜索:

 

SearchResponse response = builder.execute().actionGet();

 

1
0
分享到:
评论
5 楼 bluky999 2014-10-29  
醉仙望月 写道
SearchRequestBuilder builder= client.prepareSearch("indexName") 
                .setTypes("collectionName") 
                .setSearchType(SearchType.DEFAULT) 
                .setFrom(parameters.getStart()) 
                .setSize(parameters.getCount());

其中的indexName和collectionName是什么?随便定义的吗?如果是在哪定义的?谢谢


相当于数据库表和表明,是在创建mapping的时候定义的。
4 楼 醉仙望月 2014-10-21  
SearchRequestBuilder builder= client.prepareSearch("indexName") 
                .setTypes("collectionName") 
                .setSearchType(SearchType.DEFAULT) 
                .setFrom(parameters.getStart()) 
                .setSize(parameters.getCount());

其中的indexName和collectionName是什么?随便定义的吗?如果是在哪定义的?谢谢
3 楼 shuminghuang 2012-11-23  
parameters是我自己定义的一个类,用来保存外部传进来的参数。

问题1:ES启动的时候默认用“elasticsearch”做为cluster的名字,所以应该会自动加入es能发现的同名集群,并且自动同步数据,但前提应该是有es进程存在(不然其他集群的机器应该不会向本节点发送信息)。
问题2:开发阶段是在本机上启动es的,但是同事的机器上也有es在启动,所以能自动同步数据,可以说是有两个节点吧。
2 楼 jkbjxy 2012-11-22  
想试试楼主的程序,但是不值得parameters是哪来的呀?
1 楼 jkbjxy 2012-11-22  
感谢楼主分享,我对ES有几个疑问:
1.ES在建立Client的时候,即使不启用elasticsearch.bat,数据还是会放到本机上的es中?好像是这样的。
2.楼主用ES建立的集群,是在多个机器上建立的吗?
具体是什么样的呢?
期待楼主回答

相关推荐

Global site tag (gtag.js) - Google Analytics