elasticsearch-java api之搜索(三)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liuxiao723846/article/details/78727411

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




阅读更多

没有更多推荐了,返回首页