Database Manual / Reference / Query Language / Expressions

$filter (aggregation operator)(聚合运算符)

Definition定义

$filter
Selects a subset of an array to return based on the specified condition. Returns an array with only those elements that match the condition. The returned elements are in the original order.根据指定条件选择要返回的数组子集。返回一个仅包含符合条件的元素的数组。返回的元素按原始顺序排列。

Compatibility兼容性

You can use $filter for deployments hosted in the following environments:您可以将$filter用于在以下环境中托管的部署:

  • MongoDB Atlas: The fully managed service for MongoDB deployments in the cloud:云中MongoDB部署的完全托管服务
  • MongoDB Enterprise: The subscription-based, self-managed version of MongoDB:MongoDB的基于订阅的自我管理版本
  • MongoDB Community: The source-available, free-to-use, and self-managed version of MongoDB:MongoDB的源代码可用、免费使用和自我管理版本

Syntax语法

$filter has the following syntax:具有以下语法:

{
$filter:
{
input: <array>,
as: <string>,
cond: <expression>,
limit: <number expression>
}
}
Field字段Specification规范文档
input

An expression that resolves to an array.解析为数组的表达式

If input resolves to null or refers to a missing field, $filter returns null.如果input解析为null或引用缺少的字段,$filter将返回null

If input resolves to a non-array, non-null value, the pipeline errors.如果input解析为非数组、非null值,则管道错误。

asOptional. 可选。A name for the variable that represents each individual element of the input array. 表示input数组中每个单独元素的变量的名称。If no name is specified, the variable name defaults to this.如果未指定名称,则变量名默认为this
condAn expression that resolves to a boolean value used to determine if an element should be included in the output array. 一个解析为布尔值的表达式,用于确定元素是否应包含在输出数组中。The expression references each element of the input array individually with the variable name specified in as.表达式使用as中指定的变量名单独引用input数组的每个元素。
limit

Optional. 可选。A number expression that restricts the number of matching array elements that $filter returns. 一个数字表达式,限制$filter返回的匹配数组元素的数量。You cannot specify a limit less than 1. The matching array elements are returned in the order they appear in the input array.您不能指定小于1的限制。匹配的数组元素按照它们在输入数组中出现的顺序返回。

If the specified limit is greater than the number of matching array elements, $filter returns all matching array elements. 如果指定的limit大于匹配数组元素的数量,$filter将返回所有匹配的数组元素。If the limit is null, $filter returns all matching array elements.如果限制为null$filter将返回所有匹配的数组元素。

For more information on expressions, see Expressions.有关表达式的详细信息,请参阅表达式

Behavior行为

Example示例Results结果
{
$filter: {
input: [ 1, "a", 2, null, 3.1, Long(4), "5" ],
as: "num",
cond: { $isNumber: "$$num" }
}
}
[ 1, 2, 3.1, Long(4) ]
{
$filter: {
input: [ 1, "a", 2, null, 3.1, Long(4), "5" ],
as: "num",
cond: { $isNumber: "$$num" },
limit: 2
}
}
[ 1, 2 ]
{
$filter: {
input: [ 1, "a", 2, null, 3.1, Long(4), "5" ],
as: "num",
cond: { $isNumber: "$$num" },
limit: { $add: [ 0, 1 ] }
}
}
[ 1 ]

Examples示例

A collection sales has the following documents:集合sales有以下文档:

db.sales.insertMany( [
{
_id: 0,
items: [
{ item_id: 43, quantity: 2, price: 10, name: "pen" },
{ item_id: 2, quantity: 1, price: 240, name: "briefcase" }
]
},
{
_id: 1,
items: [
{ item_id: 23, quantity: 3, price: 110, name: "notebook" },
{ item_id: 103, quantity: 4, price: 5, name: "pen" },
{ item_id: 38, quantity: 1, price: 300, name: "printer" }
]
},
{
_id: 2,
items: [
{ item_id: 4, quantity: 1, price: 23, name: "paper" }
]
}
] )

Filter Based on Number Comparison基于数字比较的筛选器

The following example filters the items array to only include documents that have a price greater than or equal to 100:以下示例筛选items数组,使其仅包含price大于或等于100的文档:

db.sales.aggregate( [
{
$project: {
items: {
$filter: {
input: "$items",
as: "item",
cond: { $gte: [ "$$item.price", 100 ] }
}
}
}
}
] )
[
{
_id: 0,
items: [ { item_id: 2, quantity: 1, price: 240, name: 'briefcase' } ]
},
{
_id: 1,
items: [
{ item_id: 23, quantity: 3, price: 110, name: 'notebook' },
{ item_id: 38, quantity: 1, price: 300, name: 'printer' }
]
},
{ _id: 2, items: [] }
]

Use the limit Field使用限制字段

This example uses the sales collection from the previous example.此示例使用前一个示例中的sales集合。

The example uses the limit field to specify the number of matching elements returned in each items array.该示例使用limit字段指定每个items数组中返回的匹配元素的数量。

db.sales.aggregate( [
{
$project: {
items: {
$filter: {
input: "$items",
as: "item",
cond: { $gte: [ "$$item.price", 100 ] },
limit: 1
}
}
}
}
] )
[
{
_id: 0,
items: [ { item_id: 2, quantity: 1, price: 240, name: 'briefcase' } ]
},
{
_id: 1,
items: [ { item_id: 23, quantity: 3, price: 110, name: 'notebook' } ]
},
{ _id: 2, items: [] }
]

limit Greater than Possible Matches限制大于可能的匹配

This example uses the sales collection from the previous example.此示例使用前一个示例中的sales集合。

The example uses a limit field value that is larger than the possible number of matching elements that can be returned. In this case, limit does not affect the query results and returns all documents matching the $gte filter criteria.该示例使用的limit字段值大于可以返回的匹配元素的可能数量。在这种情况下,limit不会影响查询结果,并返回符合$gte筛选条件的所有文档。

db.sales.aggregate( [
{
$project: {
items: {
$filter: {
input: "$items",
as: "item",
cond: { $gte: [ "$$item.price", 100] },
limit: 5
}
}
}
}
] )
[
{
_id: 0,
items: [ { item_id: 2, quantity: 1, price: 240, name: 'briefcase' } ]
},
{
_id: 1,
items: [
{ item_id: 23, quantity: 3, price: 110, name: 'notebook' },
{ item_id: 38, quantity: 1, price: 300, name: 'printer' }
]
},
{ _id: 2, items: [] }
]

Filter Based on String Equality Match基于字符串相等匹配的筛选器

This example uses the sales collection from the previous example.此示例使用前一个示例中的sales集合。

The following aggregation filters for items that have a name value of pen.以下聚合筛选器用于筛选name值为penitems

db.sales.aggregate( [
{
$project: {
items: {
$filter: {
input: "$items",
as: "item",
cond: { $eq: [ "$$item.name", "pen"] }
}
}
}
}
] )
[
{
_id: 0,
items: [ { item_id: 43, quantity: 2, price: 10, name: 'pen' } ]
},
{
_id: 1,
items: [ { item_id: 103, quantity: 4, price: 5, name: 'pen' } ]
},
{ _id: 2, items: [] }
]

Filter Based on Regular Expression Match基于正则表达式匹配的筛选器

This example uses the sales collection from the previous example.此示例使用前一个示例中的sales集合。

The following aggregation uses $regexMatch to filter for items that have a name value that starts with p:以下聚合使用$regexMatch筛选name值以p开头的items

db.sales.aggregate( [
{
$project: {
items: {
$filter: {
input: "$items",
as: "item",
cond: {
$regexMatch: { input: "$$item.name", regex: /^p/ }
}
}
}
}
}
] )
[
{
_id: 0,
items: [ { item_id: 43, quantity: 2, price: 10, name: 'pen' } ]
},
{
_id: 1,
items: [
{ item_id: 103, quantity: 4, price: 5, name: 'pen' },
{ item_id: 38, quantity: 1, price: 300, name: 'printer' }
]
},
{
_id: 2,
items: [ { item_id: 4, quantity: 1, price: 23, name: 'paper' } ]
}
]