Trong MongoDB, $filter
toán tử đường ống tổng hợp trả về một tập hợp con của một mảng dựa trên một điều kiện cụ thể.
$filter
toán tử trả về một mảng chỉ có những phần tử phù hợp với điều kiện, theo thứ tự ban đầu của chúng.
Cú pháp
Cú pháp như sau:
{ $filter: { input: <array>, as: <string>, cond: <expression> } }
Mỗi trường như được giải thích bên dưới.
Field | Đặc điểm kỹ thuật |
---|---|
input | Một biểu thức phân giải thành một mảng. |
as | Đây là trường tùy chọn. Nó chỉ định tên cho biến đại diện cho từng phần tử riêng lẻ của input mảng. Nếu không có tên nào được chỉ định (tức là nếu bạn bỏ qua trường này), tên biến được mặc định thành this . |
cond | Một biểu thức phân giải thành giá trị boolean được sử dụng để xác định xem một phần tử có nên được đưa vào mảng đầu ra hay không. Biểu thức tham chiếu đến từng phần tử của input mảng riêng lẻ với tên biến được chỉ định trong as . |
Ví dụ
Giả sử chúng ta có một bộ sưu tập có tên là players
với các tài liệu sau
{ "_id" : 1, "player" : "Homer", "scores" : [ 1, 5, 3 ] } { "_id" : 2, "player" : "Marge", "scores" : [ 8, 17, 18 ] } { "_id" : 3, "player" : "Bart", "scores" : [ 15, 11, 8 ] }
Dưới đây là một ví dụ về việc áp dụng $filter
toán tử để lọc các phần tử mảng trong scores
lĩnh vực:
db.players.aggregate([
{
$match: { _id: { $in: [ 1, 2, 3 ] } }
},
{
$project: {
highScores: {
$filter: {
input: "$scores",
as: "score",
cond: { $gt: [ "$$score", 10 ] }
}
}
}
}
])
Kết quả:
{ "_id" : 1, "highScores" : [ ] } { "_id" : 2, "highScores" : [ 17, 18 ] } { "_id" : 3, "highScores" : [ 15, 11 ] }
Trong ví dụ này, chúng tôi đã lọc mảng thành chỉ những phần tử có giá trị lớn hơn 10. Chỉ những giá trị đó được trả về.
Bất kỳ giá trị nào nhỏ hơn 10 đều bị bỏ qua khỏi kết quả. Trong trường hợp của tài liệu đầu tiên, điều này dẫn đến một mảng trống.
Ở đây, chúng tôi đã sử dụng as
trường để đặt tên cho biến trả về score
. Sau đó, chúng tôi tham chiếu đến biến đó trong cond
trường sử dụng $$score
. Như đã đề cập, bạn có thể bỏ qua as
và sau đó tham chiếu đến biến trả về bằng cách sử dụng $$this
. Tìm hiểu thêm về điều này sau.
Mảng trống
Nếu mảng trống, thì một mảng trống được trả về.
Giả sử chúng ta có tài liệu sau trong bộ sưu tập của mình:
{ "_id" : 4, "player" : "Farnsworth", "scores" : [ ] }
Đây là những gì sẽ xảy ra khi chúng tôi áp dụng $filter
vào mảng đó:
db.players.aggregate([
{
$match: { _id: { $in: [ 4 ] } }
},
{
$project: {
highScores: {
$filter: {
input: "$scores",
as: "score",
cond: { $gt: [ "$$score", 10 ] }
}
}
}
}
])
Kết quả:
{ "_id" : 4, "highScores" : [ ] }
Loại sai
Đang áp dụng $filter
đến trường không chứa mảng sẽ trả về lỗi.
Ví dụ:
db.players.aggregate([
{
$match: { _id: { $in: [ 4 ] } }
},
{
$project: {
highScores: {
$filter: {
input: "$player",
as: "player",
cond: { $gt: [ "$$player", 10 ] }
}
}
}
}
])
Kết quả:
Error: command failed: { "ok" : 0, "errmsg" : "input to $filter must be an array not string", "code" : 28651, "codeName" : "Location28651" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:618:17 [email protected]/mongo/shell/assert.js:708:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1046:12 @(shell):1:1
Giá trị rỗng
Nếu trường chứa null
thay vì một mảng, kết quả là null
.
Hãy tưởng tượng chúng ta có tài liệu sau trong bộ sưu tập:
{ "_id" : 5, "player" : "Meg", "scores" : null }
Đây là những gì sẽ xảy ra khi chúng tôi áp dụng $filter
đến điểm scores
lĩnh vực:
db.players.aggregate([
{
$match: { _id: { $in: [ 5 ] } }
},
{
$project: {
highScores: {
$filter: {
input: "$scores",
as: "score",
cond: { $gt: [ "$$score", 10 ] }
}
}
}
}
])
Kết quả:
{ "_id" : 5, "highScores" : null }
Trường không tồn tại
Đang áp dụng $filter
đến một trường không tồn tại dẫn đến null
được trả lại.
Ví dụ:
db.players.aggregate([
{
$match: { _id: { $in: [ 5 ] } }
},
{
$project: {
highScores: {
$filter: {
input: "$name",
as: "name",
cond: { $gt: [ "$$name", 10 ] }
}
}
}
}
])
Kết quả:
{ "_id" : 5, "highScores" : null }
Tên biến là tùy chọn
Trong các ví dụ trước, tôi sử dụng as
trường để gán tên cho biến.
Như đã đề cập, as
trường là tùy chọn. Nếu bạn bỏ qua trường này, tên biến được mặc định thành this
.
Đây là một ví dụ:
db.players.aggregate([
{
$match: { _id: { $in: [ 1, 2, 3 ] } }
},
{
$project: {
highScores: {
$filter: {
input: "$scores",
cond: { $gt: [ "$$this", 10 ] }
}
}
}
}
])
Kết quả:
{ "_id" : 1, "highScores" : [ ] } { "_id" : 2, "highScores" : [ 17, 18 ] } { "_id" : 3, "highScores" : [ 15, 11 ] }
Điều này giống với ví dụ đầu tiên, ngoại trừ trong ví dụ này, chúng tôi bỏ qua as
và do đó tham chiếu đến biến bằng cách sử dụng $$this
.