Docs 菜单
Docs 主页
/
MongoDB Manual
/ / /

$filter(聚合)

在此页面上

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

根据指定条件选择要返回的数组的子集。返回一个数组,其中仅包含与条件匹配的元素。返回的元素按原始顺序排列。

可以使用 $filter 查找托管在以下环境中的部署:

  • MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务

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

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

$filter 通过以下语法实现:

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

解析为数组的表达式

如果 input 解析为 null 或指向缺失的字段,则 $filter 返回 null

如果 input 解析为非数组、非 null 值,则管道将出错。

as
可选。 代表 input 数组中每个元素的变量名称。 如果未指定名称,则变量名称默认为this
cond
可解析为布尔值的表达式,它可用于确定输出数组中是否应包含某一元素。该表达式使用 as 中指定的变量名称来单独引用 input 数组的每个元素。
limit

可选。一个数字表达式,用于限制 $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 筛选 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' } ]
}
]

后退

$expMovingAvg