概述

本文详细讲解 Elasticsearch Filter DSL 的实战用法,涵盖过滤查询、排序分页、高亮显示与批量操作。

Filter DSL

基本概念

Filter DSL 是 Elasticsearch 的过滤器查询语言,与 query 查询不同:

  • 不参与相关度评分:仅筛选符合条件的文档
  • 执行速度更快:无需计算得分,可缓存到内存
  • 适用场景:日志分析、数据分类等不需要匹配度计算的场景

使用示例

POST /book/_search
{
  "query": {
    "bool": {
      "must": { "match_all": {} },
      "filter": {
        "range": {
          "price": { "gte": 200, "lte": 1000 }
        }
      }
    }
  }
}

查询排序

默认相关性排序

POST /book/_search
{
  "query": { "match": {"description":"solr"} }
}

字段值排序

POST /book/_search
{
  "query": { "match_all": {} },
  "sort": [{ "price": { "order": "desc" } }]
}

多级排序

POST /book/_search
{
  "query": { "match_all": {} },
  "sort": [
    { "price": { "order": "desc" } },
    { "timestamp": { "order": "desc" } }
  ]
}

分页查询

POST /book/_search
{
  "query": { "match_all": {} },
  "sort": [{ "price": { "order": "desc" } }],
  "size": 2,
  "from": 0
}

结果高亮

POST /book/_search
{
  "query": { "match": { "name": "elasticsearch" } },
  "highlight": {
    "pre_tags": "<font color='pink'>",
    "post_tags": "</font>",
    "fields": [{ "name": {} }]
  }
}

批量操作

批量查询(_mget)

POST /_mget
{
  "docs": [
    { "_index": "book", "_id": 1 },
    { "_index": "book", "_id": 2 }
  ]
}

同一索引批量查询

POST /book/_mget
{
  "docs": [{ "_id": 2 }, { "_id": 3 }]
}

批量增删改(_bulk)

POST /_bulk
{ "delete": { "_index": "book", "_id": "1" }}
{ "create": { "_index": "book", "_id": "5" }}
{ "name": "test14", "price": 100.99 }
{ "update": { "_index": "book", "_id": "2" }}
{ "doc": { "name": "test" } }

注意事项

  • bulk 请求大小:一次请求建议几千个操作,大小在几 MB
  • 最佳实践:1万-5万个文档,约5-15MB,默认不超过100MB

常见错误速查

问题解决方案
Filter 看似没生效检查字段类型,确保数值/日期字段使用 range
排序不符合预期对 text 字段使用 .keyword 排序
深分页超时考虑使用 search_after/scroll 替代 from/size
高亮无输出确保 highlight.fields 与 query 字段一致
bulk 返回 400检查 JSON 格式,确保动作行与数据行严格成对