文档菜单
文档首页
/
MongoDB 手册
/ / /

$filter(聚合)

本页内容

  • 定义
  • 兼容性
  • 语法
  • 行为
  • 示例
  • 基于数字比较的筛选
  • 使用limit字段
  • limit大于可能的匹配
  • 基于字符串匹配的筛选
  • 基于正则表达式匹配的筛选
$filter

根据指定的条件选择数组的一个子集以返回。返回一个只包含匹配条件的元素的数组。返回的元素保持原始顺序。

您可以在以下环境中使用$filter

  • MongoDB Atlas:云中MongoDB部署的全面托管服务

  • MongoDB Enterprise:基于订阅的、自行管理的MongoDB版本

  • MongoDB Community:源代码可用的、免费使用并自行管理的MongoDB版本

$filter 的语法如下

{
$filter:
{
input: <array>,
as: <string>,
cond: <expression>,
limit: <number expression>
}
}
字段
指定
输入

一个解析为数组的 表达式

如果 input 解析为 null 或引用一个缺失的字段,则 $filter 返回 null

如果 input 解析为一个非数组、非空值,则管道错误。

作为
可选。一个代表 input 数组每个单个元素的 变量 名称。如果没有指定名称,则变量名称默认为 this
条件
一个解析为布尔值的 表达式,用于确定是否应将元素包含在输出数组中。该表达式使用 as 中指定的变量名单独引用 input 数组的每个元素。
限制

可选。一个限制 $filter 返回的匹配数组元素数量的数字表达式。不能指定小于 1 的限制。匹配的数组元素以在输入数组中出现的顺序返回。

如果指定的 limit 大于匹配的数组元素数量,则 $filter 返回所有匹配的数组元素。如果限制为 null,则 $filter 返回所有匹配的数组元素。

有关表达式更多信息,请参阅 表达式运算符

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

集合 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" }
]
}
] )

以下示例筛选 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: [] }
]

此示例使用前一个示例中的 sales 集合。

示例使用 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: [] }
]

此示例使用前一个示例中的 sales 集合。

该示例使用了一个值大于可能返回的匹配元素数量的 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: [] }
]

此示例使用前一个示例中的 sales 集合。

以下聚合过滤用于匹配具有 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: [] }
]

此示例使用前一个示例中的 sales 集合。

以下聚合使用 $regexMatch 来筛选具有以 p 开头的 name 值的 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' } ]
}
]

返回

$expMovingAvg