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 查询,它包含两个组成部分:
- query:这里使用了标准的匹配查询,查询字段 name 下内容为“外滩”的项目
- 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 默认最多展示搜索结果前十位数据,展示更多数据需要使用分页功能
分页查询存在两种方式:
- from+size:可随机翻页,检索数量最大 10000,会出现深度查询问题
- 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());
}