您的位置:首页 > 编程语言 > Java开发

elasticsearch-java api之搜索(三)

2017-12-06 10:35 555 查看
前两篇文章介绍了es的简单查询、聚合查询;本文再重点介绍一下es的复杂查询,包括:排序、limit、复合查询等。

1、排序:

1)代码

public static void sortQuery(String indexName, String indexType) {
QueryBuilder qb = QueryBuilders.termQuery("team", "war");

SortBuilder sortBuilder = SortBuilders.fieldSort("age")
.order(SortOrder.DESC);

SearchRequestBuilder srb = transportClient
.prepareSearch(indexName).setTypes(indexType);
srb.setQuery(qb).addSort(sortBuilder);
System.out.println(srb.toString());

SearchResponse searchResponse = srb.get();
SearchHits hits = searchResponse.getHits();
// long totalHits = hits.getTotalHits();
SearchHit[] hits2 = hits.getHits();
for (SearchHit sh : hits2) {
Map<String, Object> source = sh.getSource();
String id = sh.getId();
float score = sh.getScore();
System.out.println("source:" + source + ",id:" + id + ",score:"
+ score);
}
}


2)dsl输出:

{
"query" : {
"term" : {
"team" : "war"
}
},
"sort" : [ {
"age" : {
"order" : "desc"
}
} ]
}


3)结果输出:

source:{position=pg, name=curry, age=29, salary=1000, team=war},id:AWAlwH-I6f3B-qEuFOHZ,score:NaN
source:{position=sg, name=thompson, age=26, salary=2000, team=war},id:AWAlwH-I6f3B-qEuFOHa,score:NaN
source:{position=pf, name=green, age=26, salary=2000, team=war},id:AWAlwH-I6f3B-qEuFOHb,score:NaN


4)说明:

排序后,我们发现分数不见了,如果不加排序,可以输出分数。

2、返回指定field的结果+limit:

1)代码:

public static void limitQuery(String indexName, String indexType) {
boolean isFileds = true;
QueryBuilder qb = QueryBuilders.termQuery("team", "war");

SearchRequestBuilder srb = transportClient
.prepareSearch(indexName).setTypes(indexType);

if(isFileds) {
srb.setQuery(qb)
.addField("age")
.addField("name")
.setFrom(0).setSize(1);
} else {
srb.setQuery(qb)
.setFrom(0).setSize(1);
}
System.out.println(srb.toString());

SearchResponse searchResponse = srb.get();
SearchHits hits = searchResponse.getHits();
SearchHit[] hits2 = hits.getHits();
for (SearchHit sh : hits2) {
String id = sh.getId();
float score = sh.getScore();
if (isFileds) {
Map<String, SearchHitField> fields = sh.getFields();
Set<Entry<String, SearchHitField>> entrySet = fields.entrySet();
for (Entry<String, SearchHitField> entry : entrySet) {
System.out.print(entry.getKey()+":"+entry.getValue().getValue()+";");
}
} else {
Map<String, Object> source = sh.getSource();
System.out.println("source:" + source + ",id:" + id + ",score:"
+ score);
}
}
}
2)dsl输出:

{
"from" : 0,
"size" : 1,
"query" : {
"term" : {
"team" : "war"
}
},
"fields" : [ "age", "name" ]
}
3)结果输出:

name:curry;age:29;
4)说明:

默认情况下,ES搜索出来是source的全部字段,但有时候我们并不想获取全部字段数据,比如在开发中,我们的index中有几十个字段,每天好几十G的数据,全部返回量太大。要获取指定字段的数据有两种方式,

  1.使用默认方式查找出source所有数据,然后根据指定field进行过滤重组数据。

  2.使用addField(fields)方式请求数据,然后利用getFields方式获取结果数据。

注:若我们设置了addFields()方法,但是并没有采用hit.getFields()方式,而直接使用hit.getSource()或hit.getSourceAsString()方法获取数据,所有的数据将会是null。

3、bool复合查询:

public static void booleanQuery1(String indexName,String indexType) {
QueryBuilder qb = QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("title", "java"))
.should(QueryBuilders.termQuery("title", "hadoop"))
.mustNot(QueryBuilders.termQuery("title", "spring"));

SearchResponse searchResponse = transportClient.prepareSearch(indexName).setTypes(indexType).setQuery(qb).get();
SearchHits hits = searchResponse.getHits();
//long totalHits = hits.getTotalHits();
SearchHit[] hits2 = hits.getHits();
for (SearchHit sh:hits2) {
Map<String, Object> source = sh.getSource();
String id = sh.getId();
float score = sh.getScore();
System.out.println("source:"+source+",id:"+id+",score:"+score);
}
}


4、constant query——用来为某个字段加权,比如匹配酒店设备:多个term 泳池,花园,wifi 比如我们要将泳池的的分值放大,则将泳池的term通过该方式包一下

public static void constantQuery(String indexName,String indexType) {
QueryBuilder qb = QueryBuilders.boolQuery()
.must(QueryBuilders.constantScoreQuery(QueryBuilders.matchQuery("title", "java")).boost(1f))
.should(QueryBuilders.constantScoreQuery(QueryBuilders.termQuery("title", "elasticsearch")).boost(5f))
.should(QueryBuilders.termQuery("title", "hadoop"));

SearchResponse searchResponse = transportClient.prepareSearch(indexName).setTypes(indexType).setQuery(qb).get();
SearchHits hits = searchResponse.getHits();
//long totalHits = hits.getTotalHits();
SearchHit[] hits2 = hits.getHits();
for (SearchHit sh:hits2) {
Map<String, Object> source = sh.getSource();
String id = sh.getId();
float score = sh.getScore();
System.out.println("source:"+source+",id:"+id+",score:"+score);
}
}


5、使用head插件搜索:

我们可以在代码中打印dsl语句,然后把dsl语句放到head插件中去执行:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: