Elasticsearch查询DSL深度解析

引言
Elasticsearch提供了功能强大的Query DSL(Domain Specific Language),支持从简单的全文搜索到复杂的多条件组合查询。本文将详细介绍Elasticsearch的各种查询语法和使用方法。
查询基础
1.1 查询与过滤上下文
/**
* 查询与过滤上下文
*/
public class QueryContext {
/**
* 查询上下文 – 会计算相关性评分
*/
public void queryContext(RestHighLevelClient client) throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
// 查询上下文:计算相关性得分
builder.query(QueryBuilders.matchQuery("title", "elasticsearch"));
// 过滤上下文:不计算相关性得分,性能更好
builder.postFilter(QueryBuilders.termQuery("status", "published"));
}
}
1.2 全文搜索查询
/**
* 全文搜索查询
*/
public class FullTextQueries {
/**
* Match查询
*/
public void matchQuery(RestHighLevelClient client) throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
// 基础match查询
builder.query(QueryBuilders.matchQuery("title", "elasticsearch tutorial"));
// 带参数的match查询
builder.query(QueryBuilders.matchQuery("title", "elasticsearch tutorial")
.operator(Operator.AND)
.minimumShouldMatch("75%"));
}
/**
* MultiMatch查询
*/
public void multiMatchQuery(RestHighLevelClient client) throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
// 多字段匹配
builder.query(QueryBuilders.multiMatchQuery("elasticsearch tutorial",
"title", "content", "tags"));
}
/**
* MatchPhrase查询
*/
public void matchPhraseQuery(RestHighLevelClient client) throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
// 短语匹配
builder.query(QueryBuilders.matchPhraseQuery("title",
"elasticsearch tutorial").slop(2));
}
}
复合查询
2.1 Bool查询
/**
* Bool复合查询
*/
public class BoolQuery {
/**
* Bool查询组合
*/
public void boolQuery(RestHighLevelClient client) throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
// MUST – 必须匹配(AND关系)
boolQuery.must(QueryBuilders.matchQuery("title", "elasticsearch"));
// MUST NOT – 不能匹配(NOT关系)
boolQuery.mustNot(QueryBuilders.termQuery("status", "deleted"));
// SHOULD – 应该匹配(OR关系)
boolQuery.should(QueryBuilders.matchQuery("featured", "true"));
// FILTER – 过滤(不计算评分)
boolQuery.filter(QueryBuilders.rangeQuery("price").gte(100).lte(500));
// 最小should匹配数
boolQuery.minimumShouldMatch(1);
builder.query(boolQuery);
}
}
2.2 其他复合查询
/**
* 其他复合查询
*/
public class CompoundQueries {
/**
* ConstantScore查询
*/
public void constantScoreQuery(RestHighLevelClient client) throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
ConstantScoreQueryBuilder constantScore = QueryBuilders.constantScoreQuery(
QueryBuilders.termQuery("status", "published"));
constantScore.boost(2.0f);
builder.query(constantScore);
}
/**
* DisjunctionMax查询
*/
public void disMaxQuery(RestHighLevelClient client) throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
DisMaxQueryBuilder disMax = QueryBuilders.disMaxQuery();
disMax.add(QueryBuilders.matchQuery("title", "elasticsearch"));
disMax.add(QueryBuilders.matchQuery("content", "elasticsearch"));
disMax.tieBreaker(0.3f);
builder.query(disMax);
}
}
精确值查询
3.1 Term查询
/**
* Term精确查询
*/
public class TermQueries {
/**
* Term查询
*/
public void termQuery(RestHighLevelClient client) throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
// 精确匹配
builder.query(QueryBuilders.termQuery("status", "active"));
}
/**
* Terms查询
*/
public void termsQuery(RestHighLevelClient client) throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.termsQuery("category",
Arrays.asList("electronics", "clothing")));
}
/**
* Range查询
*/
public void rangeQuery(RestHighLevelClient client) throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.rangeQuery("price")
.gte("100")
.lte("500")
.includeLower(true)
.includeUpper(false));
}
}
特殊查询
4.1 嵌套查询
/**
* 嵌套查询
*/
public class NestedQueries {
/**
* 嵌套查询
*/
public void nestedQuery(RestHighLevelClient client) throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
NestedQueryBuilder nested = QueryBuilders.nestedQuery("attributes",
BoolQueryBuilder.must()
.add(QueryBuilders.termQuery("attributes.name", "color"))
.add(QueryBuilders.termQuery("attributes.value", "red")),
ScoreMode.Avg);
builder.query(nested);
}
}
4.2 地理查询
/**
* 地理查询
*/
public class GeoQueries {
/**
* 地理距离查询
*/
public void geoDistanceQuery(RestHighLevelClient client) throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.geoDistanceQuery("location")
.distance("10km")
.point(40.7128, -74.0060));
}
/**
* 地理边界查询
*/
public void geoBoundingBoxQuery(RestHighLevelClient client) throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.geoBoundingBoxQuery("location")
.setTopLeft(41.0, -75.0)
.setBottomRight(39.0, -73.0));
}
}
排序与分页
5.1 排序
/**
* 排序
*/
public class Sorting {
/**
* 多种排序方式
*/
public void sorting(RestHighLevelClient client) throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.matchAllQuery());
// 按相关性评分排序
builder.sort(SortOrder.DESC, "_score");
// 按字段排序
builder.sort("price", SortOrder.ASC);
// 按多个字段排序
builder.sort("price", SortOrder.ASC);
builder.sort("_score", SortOrder.DESC);
// 脚本排序
builder.sort(SortBuilders.scriptSort(
new Script(ScriptType.INLINE, "painless",
"doc['price'].value * 1.1", Collections.emptyMap()),
ScriptSortBuilder.ScriptSortType.NUMBER));
}
}
5.2 分页
/**
* 分页
*/
public class Pagination {
/**
* 分页查询
*/
public void pagination(RestHighLevelClient client) throws IOException {
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.matchAllQuery());
// from-size分页
builder.from(0);
builder.size(20);
// 深度分页问题 – 使用search_after
if (builder.from() > 10000) {
// 使用search_after代替from
}
}
}
总结
Elasticsearch Query DSL提供了丰富的查询功能,从简单的全文搜索到复杂的地理查询都能支持。掌握这些查询语法对于构建高效的搜索应用至关重要。
