前两篇文章介绍了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插件中去执行:

 
                










