Skip to content

搜索入门

搜索的两种方式

  1. URI 简单查询:在 URL 中用 q 参数,适合快速试一下。
    例:GET /my_index/_search?q=title:Elasticsearch
  2. Request Body 查询(Query DSL):在 body 里写 queryfromsizesort 等,推荐,功能完整。

本教程以 Request Body 方式为主。


搜索请求的结构

一次搜索请求通常包含:

  • query:查询条件(各种 query 类型)。
  • from / size:分页,从第几条开始、每页几条。
  • sort:排序规则。
  • _source:指定返回哪些字段(或排除哪些)。

返回结果中重点看:

  • hits.hits:命中的文档数组,每条有 _source_score 等。
  • hits.total:命中总数(可能是对象 value + relation,视版本而定)。
  • hits.max_score:最高相关度分数。

匹配查询(Match Query)

match 会对查询词做分词,再在指定字段上做全文检索,适合搜索框输入的关键词。

单字段 match

http
GET /my_index/_search
{
  "query": {
    "match": {
      "title": "Elasticsearch 入门"
    }
  }
}

会先把 “Elasticsearch 入门” 分词,再在 title 字段(需为 text)上匹配,默认多个词之间是 or 关系。

多字段 multi_match

在多个字段上查同一关键词:

http
GET /my_index/_search
{
  "query": {
    "multi_match": {
      "query": "入门",
      "fields": ["title", "content"]
    }
  }
}

常用参数

  • operator"and" 表示所有词都要出现,"or" 表示任意词出现即可(默认)。
  • minimum_should_match:至少匹配多少个词,如 "2""75%"

精确匹配(Term 与 Terms)

term 不会对查询词分词,而是精确匹配倒排索引中的词,常用于 keyword、数值、日期等。

http
GET /my_index/_search
{
  "query": {
    "term": {
      "author": "张三"
    }
  }
}

author 是 text,可能存的是分词后的词,精确匹配不到;若为 keyword 或使用 author.keyword,则可以。

terms:多值精确匹配,类似 SQL 的 IN:

http
GET /my_index/_search
{
  "query": {
    "terms": {
      "author": ["张三", "李四"]
    }
  }
}

布尔查询(Bool Query)

bool 用于组合多个条件,支持四类子句:

子句含义
must必须满足,参与算分
should满足则加分,可配合 minimum_should_match
must_not必须不满足
filter必须满足,但不参与算分,可被缓存,适合筛选条件

示例:标题包含“Elasticsearch”,作者是“张三”,年份不小于 2023:

http
GET /my_index/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "Elasticsearch" } }
      ],
      "filter": [
        { "term": { "author": "张三" } },
        { "range": { "year": { "gte": 2023 } } }
      ]
    }
  }
}

不需要相关度时,尽量用 filter,有利于缓存和性能。


范围查询(Range Query)

range 用于数值、日期等可比较的字段:

http
"range": {
  "year": { "gte": 2020, "lte": 2024 }
}
  • gte:大于等于;gt:大于
  • lte:小于等于;lt:小于

日期字段同样支持,可带格式,如 "format": "yyyy-MM-dd"


分页与深度分页

  • from:从第几条开始(从 0 计)。
  • size:每页条数。
http
GET /my_index/_search
{
  "from": 10,
  "size": 10,
  "query": { "match_all": {} }
}

注意from + size 过大会触发深度分页,成本高且默认有上限(如 10000)。更深的分页建议用 search_afterscroll(见官方文档)。


排序(Sort)

默认按 _score 降序。可按字段排序:

http
GET /my_index/_search
{
  "query": { "match": { "title": "Elasticsearch" } },
  "sort": [
    { "year": "desc" },
    { "_score": "desc" }
  ]
}

用于排序的字段最好是 keyword、数值、日期等未分词类型;对 text 排序通常用其 .keyword 子字段。按字段排序时,未指定排序的文档 _score 为 null,可能被排到最后。