参考官网 Elasticsearch Reference [7.10] » Query DSL » Compound queries

一、bool 查询

复合过滤器,将你的多个查询条件,以一定的逻辑组合在一起

  • must:所有的条件,用must组合在一起,类似于逻辑判断的意思
  • must_not:将must_not中的条件,全部不能匹配,类似于逻辑判断的意思;
  • should:所有的条件,只要其中一条满足即可,类似于逻辑判断的意思;

1.1、查询城市为北京或者杭州,运营商id不等于2的,smsContent中包含魅力或者推动的公司的短信内容;

1.1.1、RESTful 代码

POST /sms-logs-index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "terms": {
            "province": [
              "北京",
              "杭州"
            ]
          }
        }
      ],
      "must_not": [
        {
          "term": {
            "opratorId": {
              "value": "2"
            }
          }
        }
      ],
      "must": [
        {
          "match": {
            "smsContent": "魅力 推动"
          }
        }
      ]
      
    }
  }
}

1.1.2、java 代码

package com.chb.test;

import com.chb.utils.ESClient;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.Test;

import java.io.IOException;

/**
 * 复合查询
 */
public class CompoundQueryDemo {
    RestHighLevelClient client = ESClient.getClient();
    String index = "sms-logs-index";

    @Test
    public void boolQuery() throws IOException {
        // 1、创建SearchRequest对象
        SearchRequest request = new SearchRequest(index);

        // 2、指定查询条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        // 2.1、查询城市为北京或者杭州
        boolQueryBuilder.should(QueryBuilders.termQuery("province", "北京"));
        boolQueryBuilder.should(QueryBuilders.termQuery("province", "杭州"));
        // 2.2、运营商id不等于2的
        boolQueryBuilder.mustNot(QueryBuilders.termQuery("opratorId", 2));
        // 2.3、smsContent中包含魅力或者推动的公司的短信内容;
        boolQueryBuilder.must(QueryBuilders.matchQuery("smsContent", " 魅力 推动"));

        searchSourceBuilder.query(boolQueryBuilder);
        request.source(searchSourceBuilder);


        // 3、执行查询
        SearchResponse resp = client.search(request, RequestOptions.DEFAULT);

        // 4、输出结果
        for (SearchHit hit : resp.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

}

二、boosting 查询

boosting查询可以帮助我们去影响查询后的score

  • positive:只有匹配上positive的查询内容,才会被放到返回的结果集中;
  • negative:如果匹配上和positive的内容也匹配上了negative,就可以降低这样的文档的内容;
  • negative_boost:指定系数,必须小于1.0

关于查询时,分数是如何计算的思路设计:

  • 搜索的关键字在文档中出现的频次越高,分数就越高;
  • 符合搜索内容的文档内容越短,分数越高;
  • 我们在搜索时,指定的关键字也会被分词,这个被分词的内容,被分词库匹配的个数越多,分数越高。

2.1、依据smsContent字段包含魅力词语的文档信息,并且把查到的文档smsContent字段也包含传媒字样的文档得分score降低;

2.1.1、RESTful 代码

2.1.1.1、match查询分数

在这里插入图片描述

2.1.1.2、boosting查询分数

把查到的文档smsContent字段也包含传媒字样的文档,得分最高0.81875104分,排在第一;使用boosting修改这条的分值

POST /sms-logs-index/_search
{
  "query": {
    "boosting": {
      "positive": {
        "match": {
          "smsContent": "魅力"
        }
      },
      "negative": {
        "match": {
          "smsContent": "传媒"
        }
      }, 
      "negative_boost": 0.2   # 都匹配上将分数乘以negative_boost 所以 0.81875104 * 0.2 = 0.16375022
    }
  }
}

在这里插入图片描述

2.1.2、java 代码

    @Test
    public void boostingQuery() throws IOException {
        // 1、创建SearchRequest
        SearchRequest searchRequest = new SearchRequest(index);

        // 2、指定查询条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoostingQueryBuilder boostingQueryBuilder = QueryBuilders.boostingQuery(
                QueryBuilders.matchQuery("smsContent", "魅力"),
                QueryBuilders.matchQuery("smsContent", "传媒")
                ).negativeBoost(0.2f);

        searchSourceBuilder.query(boostingQueryBuilder);
        searchRequest.source(searchSourceBuilder);

        // 3、执行
        SearchResponse resp = client.search(searchRequest, RequestOptions.DEFAULT);

        // 4、输出
        for (SearchHit hit : resp.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

三、constant_score 查询

四、dis_max 查询

五、function_score 查询

关注我的公众号【宝哥大数据】, 更多干货

在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐