在本指南中,您将了解如何在一个假设的电影数据库中配置和使用 Meilisearch 的过滤器功能。

配置索引设置

假设您有一个名为 movie_ratings 的电影集合,包含以下字段:

[
  {
    "id": 458723,
    "title": "Us",
    "director": "Jordan Peele",
    "release_date": 1552521600,
    "genres": [
      "Thriller",
      "Horror",
      "Mystery"
    ],
    "rating": {
      "critics": 86,
      "users": 73
    },
  },

]

如果您想基于某个属性过滤结果,首先需要将其添加到 filterableAttributes 列表中:

curl \
  -X PUT 'MEILISEARCH_URL/indexes/movie_ratings/settings/filterable-attributes' \
  -H 'Content-Type: application/json' \
  --data-binary '[
    "genres",
    "director",
    "release_date",
    "ratings"
  ]'

此步骤是强制性的,无法在搜索时完成。更新 filterableAttributes 需要 Meilisearch 重新索引所有数据,所需时间与数据集的大小和复杂程度成正比。

默认情况下,filterableAttributes 为空。如果不先将属性显式添加到 filterableAttributes 列表中,过滤器将无法工作。

搜索时使用 filter 参数

在更新了 filterableAttributes 索引设置后,您可以使用 filter 来精确调整搜索结果。

filter 是一个可在搜索时使用的参数,它接受基于 filterableAttributes 列表中任何属性构建的过滤表达式

以下代码示例返回 1995 年 3 月 18 日之后上映的《复仇者联盟》电影:

curl \
  -X POST 'MEILISEARCH_URL/indexes/movie_ratings/search' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "q": "Avengers",
    "filter": "release_date > 795484800"
  }'

使用点号表示法可以根据文档的嵌套字段进行过滤。以下查询仅返回用户评价良好的惊悚片:

curl \
  -X POST 'MEILISEARCH_URL/indexes/movie_ratings/search' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "q": "thriller",
    "filter": "rating.users >= 90"
  }'

您还可以组合多个条件。例如,可以限制搜索范围,使其仅包含由 Tim BurtonChristopher Nolan 执导的《蝙蝠侠》电影:

curl \
  -X POST 'MEILISEARCH_URL/indexes/movie_ratings/search' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "q": "Batman",
    "filter": "release_date > 795484800 AND (director = \"Tim Burton\" OR director = \"Christopher Nolan\")"
  }'

注意这里的括号是必需的:如果没有括号,过滤器会返回由 Tim Burton 执导且在 1995 年后上映的电影,或者任何由 Christopher Nolan 执导的电影(而不限制其上映日期)。这是因为 AND 运算符的优先级高于 OR

如果您只想获取不是由 Tim Burton 执导的近期《人猿星球》电影,可以使用以下过滤器:

curl \
  -X POST 'MEILISEARCH_URL/indexes/movie_ratings/search' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "q": "Planet of the Apes",
    "filter": "release_date > 1577884550 AND (NOT director = \"Tim Burton\")"
  }' \
release_date > 1577884550 AND (NOT director = "Tim Burton" AND director EXISTS)

同义词不适用于过滤器。这意味着如果您将 SFSan Francisco 设为同义词,使用 SFSan Francisco 进行过滤会显示不同的结果。