一。多字段查询QueryString
流程:
- 会对查询条件进行分词。
- 然后将分词后的查询条件和词条进行等值匹配
- 默认取并集(OR)
- 可以指定多个查询字段
1.1 restAPI
例:在title和brandName字段中只要有一个字段包含“小米手机”分词字样的话,都查出来:
GET goods/_search
{
"query": {
"query_string": {
"fields": ["title","categoryName","brandName"],
"query": "苹果手机"
}
}
}
例: title 和 brandName中都得包含“小米”或“手机”:
GET goods/_search
{
"query": {
"query_string": {
"fields": ["title","brandName"],
"query": "小米 AND 手机"
}
}
}
例 :title name字段中有一个字段包含 华为 或 手机 或 AND 三个分词就行,查询粒度大。
不支持连接符,按照“华为”“AND”“手机” 三个词查询:
GET goods/_search
{
"query": {
"simple_query_string": {
"fields": ["title","categoryName","brandName"],
"query": "华为 AND 手机"
}
}
}
1.2 javaAPI
@Test
public void testStringQuery() throws IOException {
// 1.创建请求
SearchRequest searchRequest = new SearchRequest("goods");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
★★★ QueryStringQueryBuilder field = QueryBuilders.queryStringQuery("小米 AND 手机").field("title").field("brandName");
searchSourceBuilder.query(field);
searchSourceBuilder.sort("price", SortOrder.DESC);
searchRequest.source(searchSourceBuilder);
// 2.执行操作
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 3.获取结果
List<Goods> goodsList = new ArrayList<>();
SearchHits hits = searchResponse.getHits();
long value = hits.getTotalHits().value;
System.out.println(value);
SearchHit[] smallHits = hits.getHits();
for (SearchHit smallHit : smallHits) {
String sourceAsString = smallHit.getSourceAsString();
Goods goods = JSON.parseObject(sourceAsString, Goods.class);
goodsList.add(goods);
}
for (Goods goods : goodsList) {
System.out.println(goods);
}
}
SimpleQueryString:
QueryBuilders.simpleQueryStringQuery("小米 AND 手机").field("title").field("brandName");
二。布尔查询
2.1 rest:
1概念:
对多个查询条件连接
2链接方式:
- must(and):条件必须成立
- must_not(not):条件必须不成立
- should(or):条件可以成立
- filter:条件必须成立,性能比must高。负责上面三个条件查询结果的过滤。不会计算相关度score,因为耗性能。主要放: range 1000-2000,term 华为 。
# title必须包含手机,品牌必须小米,品牌可以是诺基亚,不能是华为,价格1000-2000
GET goods/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"title": "手机"
}
},
{
"term": {
"brandName": {
"value": "小米"
}
}
}
],
"should": [
{
"term": {
"brandName": {
"value": "诺基亚"
}
}
}
],
"must_not": [
{
"term": {
"brandName": {
"value": "华为"
}
}
}
],
"filter": [
{
"range": {
"price": {
"gte": 1000,
"lte": 2000
}
}
}
]
}
}
}
2.2 java:
@Test
public void testBoolQuery() throws IOException {
// 1.创建请求
SearchRequest searchRequest = new SearchRequest("goods");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "手机");
boolQueryBuilder.must(matchQueryBuilder);
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("brandName", "小米");
boolQueryBuilder.must(termQueryBuilder);
TermQueryBuilder termQueryBuilder1 = QueryBuilders.termQuery("brandName", "诺基亚");
boolQueryBuilder.should(termQueryBuilder1);
TermQueryBuilder termQueryBuilder2 = QueryBuilders.termQuery("brandName", "华为");
boolQueryBuilder.mustNot(termQueryBuilder2);
RangeQueryBuilder price = QueryBuilders.rangeQuery("price").gte(1000).lte(2000);
boolQueryBuilder.filter(price);
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
// 2.执行操作
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 3.获取结果
List<Goods> goodsList = new ArrayList<>();
SearchHits hits = searchResponse.getHits();
long value = hits.getTotalHits().value;
System.out.println(value);
SearchHit[] smallHits = hits.getHits();
for (SearchHit smallHit : smallHits) {
String sourceAsString = smallHit.getSourceAsString();
Goods goods = JSON.parseObject(sourceAsString, Goods.class);
goodsList.add(goods);
}
for (Goods goods : goodsList) {
System.out.println(goods);
}
}
三。agg聚合查询
查询出结果以后,再把结果进行聚合。所以agg聚合是和query平行的
3.1 rest
# 每个品牌手机的个数
# select brandName count(1) as group_by_brandName from goods where title like "%手机%" group by brandName
GET goods/_search
{
"query": {
"match": {
"title": "手机"
}
},
"aggs": {
"group_by_brandName": {
"terms": {
"field": "brandName"
}
}
}
}
聚合查询结果:
"aggregations" : {
"group_by_brandName" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 113,
"buckets" : [
{
"key" : "三星",
"doc_count" : 127
},
{
"key" : "苹果",
"doc_count" : 93
},
{
"key" : "中国移动",
"doc_count" : 79
},
{
"key" : "联想",
"doc_count" : 68
},
{
"key" : "华为",
"doc_count" : 66
},
{
"key" : "酷派",
"doc_count" : 44
},
{
"key" : "诺基亚",
"doc_count" : 41
},
{
"key" : "飞利浦",
"doc_count" : 33
},
{
"key" : "OPPO",
"doc_count" : 30
},
{
"key" : "HTC",
"doc_count" : 23
}
]
}
}
3.2 java
@Test
public void testAggQuery() throws IOException {
// 1.创建请求
SearchRequest searchRequest = new SearchRequest("goods");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "手机");
searchSourceBuilder.query(matchQueryBuilder);
// 不要具体数据
searchSourceBuilder.size(0);
// 设置聚合
TermsAggregationBuilder group_by_brandName = AggregationBuilders.terms("group_by_brandName").field("brandName");
searchSourceBuilder.aggregation(group_by_brandName);
searchRequest.source(searchSourceBuilder);
// 2.执行操作
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 3.获取聚合结果
Aggregations aggregations = searchResponse.getAggregations();
Terms aggregation = aggregations.get("group_by_brandName");
List<? extends Terms.Bucket> buckets = aggregation.getBuckets();
for (Terms.Bucket bucket : buckets) {
String keyAsString = bucket.getKeyAsString();
System.out.println(keyAsString);
long docCount = bucket.getDocCount();
System.out.println(docCount);
}
}
3.3 查询手机均价 restAPI
# 手机均价?
# select avg(price) as avg_price from goods where title like "%手机%"
GET goods/_search
{
"query": {
"match": {
"title": "手机"
}
},
"size": 0,
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
3.4 查询手机均价 javaAPI
@Test
public void testAggQuery2() throws IOException {
// 1.创建请求
SearchRequest searchRequest = new SearchRequest("goods");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "手机");
searchSourceBuilder.query(matchQueryBuilder);
// 不要具体hits数据,只看聚合结果
searchSourceBuilder.size(0);
// 设置聚合
AvgAggregationBuilder avg_price = AggregationBuilders.avg("avg_price").field("price");
searchSourceBuilder.aggregation(avg_price);
searchRequest.source(searchSourceBuilder);
// 2.执行操作
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 3.获取聚合结果
Aggregations aggregations = searchResponse.getAggregations();
Avg aggregation = aggregations.get("avg_price");
double value = aggregation.getValue();
System.out.println(value);
}
四。subagg子聚合
4.1 rest
# 每个品牌手机的均价
# select brandName avg(price) as avg_price from goods where title like "%手机%" group by brandName
GET goods/_search
{
"query": {
"match": {
"title": "手机"
}
},
"size": 0,
"aggs": {
"group_brand": {
"terms": {
"field": "brandName"
},
"aggs": {
"avg_brand": {
"avg": {
"field": "price"
}
}
}
}
}
}
部分结果:
"aggregations" : {
"group_brand" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 113,
"buckets" : [
{
"key" : "三星",
"doc_count" : 127,
"avg_brand" : {
"value" : 3013.48031496063
}
},
{
"key" : "苹果",
"doc_count" : 93,
"avg_brand" : {
"value" : 5626.763440860215
}
},......
4.2java
@Test
public void testAggQuery3() throws IOException {
// 1.创建请求
SearchRequest searchRequest = new SearchRequest("goods");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "手机");
searchSourceBuilder.query(matchQueryBuilder);
// 不要具体数据 ,只显示聚合出来的结果
searchSourceBuilder.size(0);
// 设置聚合
TermsAggregationBuilder group_by_brandName = AggregationBuilders.terms("group_brand").field("brandName");
AvgAggregationBuilder field = AggregationBuilders.avg("avg_brand").field("price");
// subagg 父聚合中的子聚合
group_by_brandName.subAggregation(field);
searchSourceBuilder.aggregation(group_by_brandName);
searchRequest.source(searchSourceBuilder);
// 2.执行操作
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 3.获取聚合结果
Aggregations aggregations = searchResponse.getAggregations();
Terms aggregation = aggregations.get("group_brand");
List<? extends Terms.Bucket> buckets = aggregation.getBuckets();
for (Terms.Bucket bucket : buckets) {
String keyAsString = bucket.getKeyAsString();
System.out.println(keyAsString);
long docCount = bucket.getDocCount();
System.out.println(docCount);
Aggregations aggregations1 = bucket.getAggregations();
Avg avg_brand = aggregations1.get("avg_brand"); //拿到具体聚合
System.out.println(avg_brand.getValue());
}
}