filter 搜索参数需要一个过滤表达式。过滤表达式由属性、值和多个运算符组成。

filter 需要一个包含一个或多个条件的过滤表达式。过滤表达式可以写成字符串、数组,或者两者的混合形式。

数据类型

过滤器接受数字和字符串值。空字段或包含空数组的字段将被忽略。

过滤器不适用于 NaN 和无限值,如 inf-inf,因为它们不受 JSON 支持。如果你将无限值和 NaN 值解析为字符串,则可以过滤它们,但在处理 _geo 字段时除外。

为获得最佳结果,请在字段中强制执行同质类型,尤其是在处理大数字时。Meilisearch 在索引数据时不强制执行特定模式,但过滤引擎可能会强制转换 value 的类型。这可能导致未定义的行为,例如当大浮点数被强制转换为整数时。

条件

条件是过滤器的基本构成要素。它们以 attribute OPERATOR value 格式编写,其中

  • attribute 是你希望过滤的字段属性
  • OPERATOR 可以是 =!=>>=<<=TOEXISTSINNOTANDOR
  • valueOPERATOR 应该在 attribute 中查找的值

示例

一个基本条件,请求 genres 属性等于 horror 的电影

genres = horror

包含空格的字符串值必须用单引号或双引号括起来

director = 'Jordan Peele'
director = "Tim Burton"

过滤运算符

相等 (=)

相等运算符 (=) 返回所有包含给定属性特定值的文档

genres = action

对字符串操作时,= 不区分大小写。

相等运算符不返回 null 和空数组的任何结果。

不相等 (!=)

不相等运算符 (!=) 返回所有未被相等运算符选中的文档。对字符串操作时,!= 不区分大小写。

以下表达式返回所有不属于 action 类型的电影

genres != action

比较 (>, <, >=, <=)

比较运算符 (>, <, >=, <=) 选择满足比较条件的文档。比较运算符适用于数字和字符串值。

以下表达式返回所有用户评分高于 85 的文档

rating.users > 85

字符串比较按字典顺序解析:符号、数字、然后按字母顺序排列的字母。以下表达式返回所有在 2004 年第一天之后发布的文档

release_date > 2004-01-01

TO

TO 等同于 >= AND <=。以下表达式返回所有评分在 80 或以上但低于 90 的文档

rating.users 80 TO 89

EXISTS

EXISTS 运算符检查字段是否存在。空值或 null 值的字段也被视为存在。

以下表达式返回所有包含 release_date 字段的文档

release_date EXISTS

上述表达式的否定形式可以以两种等效方式编写

release_date NOT EXISTS
NOT release_date EXISTS

IS EMPTY

IS EMPTY 运算符选择指定属性存在但包含空值的文档。以下表达式仅返回 overview 字段为空的文档

overview IS EMPTY

IS EMPTY 匹配以下 JSON 值

  • ""
  • []
  • {}

Meilisearch 不将 null 值视为空。要匹配 null 字段,请使用 IS NULL 运算符。

使用 NOT 构建 IS EMPTY 的否定形式

overview IS NOT EMPTY
NOT overview IS EMPTY

IS NULL

IS NULL 运算符选择指定属性存在但包含 null 值的文档。以下表达式仅返回 overview 字段为 null 的文档

overview IS NULL

使用 NOT 构建 IS NULL 的否定形式

overview IS NOT NULL
NOT overview IS NULL

IN

IN 通过接受一个由方括号分隔的逗号分隔值数组来组合相等运算符。它选择所有其所选字段包含至少一个指定值的文档。

以下表达式返回所有 genres 包含 horrorcomedy 或两者的文档

genres IN [horror, comedy]
genres = horror OR genres = comedy

上述表达式的否定形式可以写为

genres NOT IN [horror, comedy]
NOT genres IN [horror, comedy]

CONTAINS

实验性

CONTAINS 过滤包含指定字符串模式部分匹配的结果,类似于 SQL LIKE

以下表达式返回所有名称中包含 "kef" 的乳制品

dairy_products.name CONTAINS kef

上述表达式的否定形式可以写为

dairy_products.name NOT CONTAINS kef
NOT dairy_product.name CONTAINS kef

这是一个实验性功能。使用实验性功能端点来激活它

curl \
  -X PATCH 'MEILISEARCH_URL/experimental-features/' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "containsFilter": true
  }'

这也会启用 STARTS WITH 运算符。

STARTS WITH

实验性

STARTS WITH 过滤值以指定字符串模式开始的结果。

以下表达式返回所有名称以 "kef" 开头的乳制品

dairy_products.name STARTS WITH kef

上述表达式的否定形式可以写为

dairy_products.name NOT STARTS WITH kef
NOT dairy_product.name STARTS WITH kef

这是一个实验性功能。使用实验性功能端点来激活它

curl \
  -X PATCH 'MEILISEARCH_URL/experimental-features/' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "containsFilter": true
  }'

这也会启用 CONTAINS 运算符。

NOT

否定运算符 (NOT) 选择所有不满足条件的文档。它的优先级高于 ANDOR

以下表达式将返回所有 genres 不包含 horror 的文档,以及缺少 genres 字段的文档

NOT genres = horror

过滤表达式

你可以使用 ANDOR 对基本条件进行分组来构建过滤表达式。过滤表达式可以写成字符串、数组,或者两者的混合形式。

过滤表达式分组运算符

AND

AND 连接两个条件,并且只返回同时满足这两个条件的文档。AND 的优先级高于 OR

以下表达式返回所有匹配两个条件的文档

genres = horror AND director = 'Jordan Peele'

OR

OR 连接两个条件,并返回满足其中至少一个条件的结果。

以下表达式返回匹配任一条件的文档

genres = horror OR genres = comedy

使用字符串运算符和括号创建过滤表达式

Meilisearch 从左到右读取字符串表达式。你可以使用括号来确保表达式被正确解析。

例如,如果你希望结果只包含 1995 年 3 月之后发布的喜剧恐怖文档,则以下查询中的括号是强制性的

(genres = horror OR genres = comedy) AND release_date > 795484800

未能添加这些括号将导致相同的查询被解析为

genres = horror OR (genres = comedy AND release_date > 795484800)

翻译成中文,上述表达式将只返回 1995 年 3 月之后发布的喜剧电影,或者恐怖电影(无论其 release_date 如何)。

当创建的表达式中字段名或值与过滤器运算符(如 ANDNOT)相同时,你必须将其用引号括起来:title = "NOT" OR title = "AND"

使用数组创建过滤表达式

数组表达式通过嵌套字符串数组建立逻辑连接。数组过滤器最大深度为两层。包含三层或更多层嵌套的表达式将抛出错误。

外部数组元素通过 AND 运算符连接。以下表达式返回 Jordan Peele 导演的 恐怖 电影

["genres = horror", "director = 'Jordan Peele'"]

内部数组元素通过 OR 运算符连接。以下表达式返回 恐怖喜剧 电影

[["genres = horror", "genres = comedy"]]

内部和外部数组可以自由组合。以下表达式返回 Jordan Peele 导演的 恐怖喜剧 电影

[["genres = horror", "genres = comedy"], "director = 'Jordan Peele'"]

组合数组和字符串运算符

你也可以创建同时使用数组和字符串语法的过滤表达式。

以下过滤器以字符串形式编写,仅返回不属于 Jordan Peele 导演的、且属于 喜剧恐怖 类型的电影

"(genres = comedy OR genres = horror) AND director != 'Jordan Peele'"

你可以通过混合数组和字符串编写相同的过滤器

[["genres = comedy", "genres = horror"], "NOT director = 'Jordan Peele'"]