【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());
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zhillery

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值