【SpringCloud】微服务技术栈入门7 - DSL使用

DSL


全文查询

查询索引 hotel 下的所有内容

match_all 查询全部内容

GET /hotel/_search
{
    
    
  "query": {
    
    
    "match_all": {
    
    }
  }
}

multi_match 查询方式:在指定的 fields 查询 query 的内容

GET /hotel/_search
{
    
    
  "query": {
    
    
    "multi_match": {
    
    
      "query": "酒店",
      "fields": ["brand","name"]
    }
  }
}

精确查询

term 匹配(精确匹配):根据字段名称来精确查找指定内容,只要 value 的值有一丝不符合就查询不到

GET /hotel/_search
{
    
    
  "query": {
    
    
    "term": {
    
    
      // 字段名称
      "brand": {
    
    
        // 字段内容
        "value": "华美达"
      }
    }
  }
}

range 查询(范围模糊查询)

GET /hotel/_search
{
    
    
  "query": {
    
    
    "range": {
    
    
      // 字段名称
      "price": {
    
    
        "gte": 100, // gte大于且等于
        "lte": 300  // lte小于且等于
      }
    }
  }
}

其余查询方法

FunctionScoreQuery 方法分数加权查询
可以将其看成一个带权重的查询方式

下方查询使用了 function_score 查询,它包含两个组成部分:

  1. query:这里使用了标准的匹配查询,查询字段 name 下内容为“外滩”的项目
  2. functions:加权方法,下方加了一个过滤器 filter,表示当精准匹配到字段 brand 下的“如家”时,为此平分乘以权重值 weight

被加权的字段会在查询结果中排列靠前,故此方法可以灵活调整查询结果

GET /hotel/_search
{
    
    
  "query": {
    
    
    "function_score": {
    
    
      "query": {
    
    
        "match": {
    
    
          "name": "外滩"
        }
      },
      "functions": [
        {
    
    
          "filter": {
    
    
            "term": {
    
    
              "brand": "如家"
            }
          },
          "weight": 10
        }
      ]
    }
  }
}

BooleanQuery 布尔查询

布尔查询包含四个组合:

  • must 必须匹配的查询
  • should 选择性匹配的查询
  • must_not 必须不匹配
  • filter 必须匹配,但是不参与几计分

案例示范:查询字段 name 必须为为如家且价格必须不大于 400 元的记录

GET /hotel/_search
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "must": [
        {
    
    
          "match": {
    
    
            "name": "如家"
          }
        }
      ],
      "must_not": [
        {
    
    
          "range": {
    
    
            "price": {
    
    
              "gt": 400
            }
          }
        }
      ]
    }
  }
}

搜索结果

sort 排序

GET /hotel/_search
{
    
    
  "query": {
    
    
    "match_all": {
    
    }
  },
  "sort": [
    {
    
    
      "score": {
    
    
        "order": "desc"
      },
      "price": {
    
    
        "order": "asc"
      }
    }
  ]
}

es 默认最多展示搜索结果前十位数据,展示更多数据需要使用分页功能

分页查询存在两种方式:

  1. from+size:可随机翻页,检索数量最大 10000,会出现深度查询问题
  2. after+size:不可随机翻页,无检索上限,只能逐页查询
GET /hotel/_search
{
    
    
  "query": {
    
    
    "match_all": {
    
    }
  },
  "from": 10, // 查询起始位,从第几个文档开始
  "size": 20, // 期望获取多少个文档
  "sort": [
    {
    
    
      "price": {
    
    
        "order": "desc"
      }
    }
  ]
}

高亮

GET /hotel/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "name": "如家"
    }
  },
  "highlight": {
    
    
    "fields": {
    
    
      "name": {
    
    
        "require_field_match": "false"
      }
    }
  }
}

用 RestClient 实现 DSL

matchAll

SearchRequest 执行搜索匹配请求,使用 source 规定搜索方法

SearchHits 获取所有命中的文档
SearchHit[] 将每个文档化为单个 hit 后存储到该数组内部
SearchHit 最后对数组 foreach,得到单个 hit 对象,使用字符串转换方法显示 json 给客户

@Test
void testAll() throws IOException {
    
    
    SearchRequest request = new SearchRequest("hotel");
    request.source().query(QueryBuilders.matchAllQuery());
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);

    SearchHits hits = response.getHits();
    long total = hits.getTotalHits().value;

    SearchHit[] searchHits = hits.getHits();
    for (SearchHit hit : searchHits) {
    
    
        String sourceAsString = hit.getSourceAsString();
        System.out.println(sourceAsString);
    }
}

全文检索

指定单个或者多个字段进行查询,使用 QueryBuilders.matchQuery

SearchRequest request = new SearchRequest("hotel");
request.source().query(QueryBuilders.matchQuery("all","如家"));

布尔查询

通过构建一个 BoolQueryBuilder ,将其作为查询参数放到 request 里面,然后执行查询

@Test
void testBooleanMatch() throws IOException {
    
    
    SearchRequest request = new SearchRequest("hotel");
    BoolQueryBuilder builder = QueryBuilders.boolQuery();
    builder.must(QueryBuilders.termQuery("city", "杭州"));
    builder.filter(QueryBuilders.rangeQuery("price").lte(250));
    request.source().query(builder);
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);

    for (SearchHit hit : response.getHits().getHits()) System.out.println(hit.getSourceAsString());
}

分页查询

@Test
void testPage() throws IOException {
    
    
    SearchRequest request = new SearchRequest("hotel");
    request.source().query(QueryBuilders.matchAllQuery());
    request.source().from(0).size(10);  // 指定从第几个文档开始查询,以及查询文档的数量
    request.source().sort("price", SortOrder.ASC); // 根据price字段的升序排列

    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    for (SearchHit hit : response.getHits().getHits()) System.out.println(hit.getSourceAsString());
}

高亮显示

@Test
void testHighLight() throws IOException {
    
    
    SearchRequest request = new SearchRequest("hotel");
    request.source().query(QueryBuilders.matchQuery("all", "如家"));
    request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));

    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    for (SearchHit hit : response.getHits().getHits()) System.out.println(hit.getSourceAsString());
}

猜你喜欢

转载自blog.csdn.net/delete_you/article/details/133611854
DSL
今日推荐