Lỗi là do nó không còn là một mảng sau khi bạn $unwind
và do đó không còn là một đối số hợp lệ với $size
.
Bạn dường như đang cố gắng "hợp nhất" một vài câu trả lời hiện có mà không hiểu những gì họ đang làm. Những gì bạn thực sự muốn ở đây là $filter
và $size
db.collection.aggregate[[
{ "$project": {
"total": {
"$size": {
"$filter": {
"input": "$Array",
"cond": { "$eq": [ "$$this.field1", "a" ] }
}
}
}
}}
]]
Hoặc "Tái tạo bánh xe" bằng cách sử dụng
db.collection.aggregate[[
{ "$project": {
"total": {
"$reduce": {
"input": "$Array",
"initialValue": 0,
"in": {
"$sum": [
"$$value",
{ "$cond": [{ "$eq": [ "$$this.field1", "a" ] }, 1, 0] }
}
}
}
}}
]]
1:db.collection.aggregate[[
{ "$project": {
"total": {
"$reduce": {
"input": "$Array",
"initialValue": 0,
"in": {
"$sum": [
"$$value",
{ "$cond": [{ "$eq": [ "$$this.field1", "a" ] }, 1, 0] }
}
}
}
}}
]]
Hoặc cho những gì bạn đã cố gắng làm với $unwind
, bạn thực sự
db.collection.aggregate[[
{ "$project": {
"total": {
"$reduce": {
"input": "$Array",
"initialValue": 0,
"in": {
"$sum": [
"$$value",
{ "$cond": [{ "$eq": [ "$$this.field1", "a" ] }, 1, 0] }
}
}
}
}}
]]
3 một lần nữa để "đếm" có bao nhiêu trận đấu có:db.collection.aggregate[[
{ "$unwind": "$Array" },
{ "$match": { "Array.field1": "a" } },
{ "$group": {
"_id": "$_id",
"total": { "$sum": 1 }
}}
]]
Hai hình thức đầu tiên là "tối ưu" cho môi trường MongoDB hiện đại. Hình thức cuối cùng với $unwind
và
db.collection.aggregate[[
{ "$project": {
"total": {
"$reduce": {
"input": "$Array",
"initialValue": 0,
"in": {
"$sum": [
"$$value",
{ "$cond": [{ "$eq": [ "$$this.field1", "a" ] }, 1, 0] }
}
}
}
}}
]]
3 là cấu trúc "di sản" thực sự không cần thiết cho loại hoạt động này kể từ MongoDB 2.6, mặc dù với một số toán tử hơi khác nhau.Trong hai điều đầu tiên, về cơ bản, chúng tôi đang so sánh giá trị
db.collection.aggregate[[
{ "$project": {
"total": {
"$reduce": {
"input": "$Array",
"initialValue": 0,
"in": {
"$sum": [
"$$value",
{ "$cond": [{ "$eq": [ "$$this.field1", "a" ] }, 1, 0] }
}
}
}
}}
]]
6 của mỗi phần tử mảng trong khi nó vẫn là một mảng. Cả $filter
và db.collection.aggregate[[
{ "$project": {
"total": {
"$reduce": {
"input": "$Array",
"initialValue": 0,
"in": {
"$sum": [
"$$value",
{ "$cond": [{ "$eq": [ "$$this.field1", "a" ] }, 1, 0] }
}
}
}
}}
]]
1 đều là những người vận hành hiện đại được thiết kế để hoạt động với một mảng hiện có. So sánh tương tự được thực hiện trên mỗi người bằng cách sử dụng toán tử db.collection.aggregate[[
{ "$project": {
"total": {
"$reduce": {
"input": "$Array",
"initialValue": 0,
"in": {
"$sum": [
"$$value",
{ "$cond": [{ "$eq": [ "$$this.field1", "a" ] }, 1, 0] }
}
}
}
}}
]]
9 tổng hợp trả về giá trị boolean dựa trên việc các đối số được đưa ra có "bằng nhau" hay không. Trong trường hợp này trên mỗi thành viên mảng theo giá trị dự kiến là db.collection.aggregate[[
{ "$unwind": "$Array" },
{ "$match": { "Array.field1": "a" } },
{ "$group": {
"_id": "$_id",
"total": { "$sum": 1 }
}}
]]
0.Trong trường hợp của $filter
, mảng thực sự vẫn còn nguyên ngoại trừ bất kỳ yếu tố nào không đáp ứng điều kiện được cung cấp trong
db.collection.aggregate[[
{ "$unwind": "$Array" },
{ "$match": { "Array.field1": "a" } },
{ "$group": {
"_id": "$_id",
"total": { "$sum": 1 }
}}
]]
2 được loại bỏ khỏi mảng. Vì chúng tôi vẫn có một "mảng" làm đầu ra, sau đó chúng tôi có thể sử dụng toán tử $size
để đo số lượng phần tử mảng còn lại sau khi điều kiện lọc đó được xử lý.Mặt khác,
db.collection.aggregate[[
{ "$project": {
"total": {
"$reduce": {
"input": "$Array",
"initialValue": 0,
"in": {
"$sum": [
"$$value",
{ "$cond": [{ "$eq": [ "$$this.field1", "a" ] }, 1, 0] }
}
}
}
}}
]]
1 hoạt động thông qua các phần tử mảng và cung cấp một biểu thức trên mỗi phần tử và giá trị "tích lũy" được lưu trữ, mà chúng tôi đã khởi tạo với db.collection.aggregate[[
{ "$unwind": "$Array" },
{ "$match": { "Array.field1": "a" } },
{ "$group": {
"_id": "$_id",
"total": { "$sum": 1 }
}}
]]
5. Trong trường hợp này, thử nghiệm db.collection.aggregate[[
{ "$project": {
"total": {
"$reduce": {
"input": "$Array",
"initialValue": 0,
"in": {
"$sum": [
"$$value",
{ "$cond": [{ "$eq": [ "$$this.field1", "a" ] }, 1, 0] }
}
}
}
}}
]]
9 tương tự được áp dụng trong toán tử ____27. Đây là một toán tử có điều kiện "ternary" hoặc db.collection.aggregate[[
{ "$unwind": "$Array" },
{ "$match": { "Array.field1": "a" } },
{ "$group": {
"_id": "$_id",
"total": { "$sum": 1 }
}}
]]
8 cho phép biểu thức được thử nghiệm trả về giá trị boolean để trả về giá trị db.collection.aggregate[[
{ "$unwind": "$Array" },
{ "$match": { "Array.field1": "a" } },
{ "$group": {
"_id": "$_id",
"total": { "$sum": 1 }
}}
]]
9 khi { "$group": {
"_id": "$_id",
"Array": { "$push": "$Array" },
"total": { "$sum": 1 }
}}
0 hoặc giá trị { "$group": {
"_id": "$_id",
"Array": { "$push": "$Array" },
"total": { "$sum": 1 }
}}
1 khi { "$group": {
"_id": "$_id",
"Array": { "$push": "$Array" },
"total": { "$sum": 1 }
}}
2.Trong biểu thức đó, chúng tôi trả về
{ "$group": {
"_id": "$_id",
"Array": { "$push": "$Array" },
"total": { "$sum": 1 }
}}
3 hoặc { "$group": {
"_id": "$_id",
"Array": { "$push": "$Array" },
"total": { "$sum": 1 }
}}
4 tương ứng và cung cấp kết quả tổng thể của việc thêm giá trị trả về đó và "bộ tích lũy" hiện tại { "$group": {
"_id": "$_id",
"Array": { "$push": "$Array" },
"total": { "$sum": 1 }
}}
5 với toán tử { "$group": {
"_id": "$_id",
"Array": { "$push": "$Array" },
"total": { "$sum": 1 }
}}
6 để cộng chúng lại với nhau.Mẫu cuối cùng được sử dụng $unwind
trên mảng. Những gì thực sự làm là giải mã các thành viên mảng để tạo một "tài liệu mới" cho mọi thành viên mảng và các trường phụ huynh liên quan đến tài liệu gốc. "Bản sao" này có hiệu quả là tài liệu chính cho mọi thành viên mảng.
Khi bạn $unwind
, cấu trúc của các tài liệu được thay đổi thành dạng "phẳng hơn". Đây là lý do tại sao sau đó bạn có thể thực hiện giai đoạn đường ống
{ "$group": {
"_id": "$_id",
"Array": { "$push": "$Array" },
"total": { "$sum": 1 }
}}
9 tiếp theo để xóa các tài liệu không phù hợp.Điều này đưa chúng ta đến
db.collection.aggregate[[
{ "$project": {
"total": {
"$reduce": {
"input": "$Array",
"initialValue": 0,
"in": {
"$sum": [
"$$value",
{ "$cond": [{ "$eq": [ "$$this.field1", "a" ] }, 1, 0] }
}
}
}
}}
]]
3 được áp dụng để "mang lại với nhau" tất cả các thông tin liên quan đến một khóa chung. Trong trường hợp này, đó là trường { "_id" : 1, "item" : "ABC1", "description" : "product 1", colors: [ "blue", "black", "red" ] } { "_id" : 2, "item" : "ABC2", "description" : "product 2", colors: [ "purple" ] } { "_id" : 3, "item" : "XYZ1", "description" : "product 3", colors: [ ] } { "_id" : 4, "item" : "ZZZ1", "description" : "product 4 - missing colors" } { "_id" : 5, "item" : "ZZZ2", "description" : "product 5 - colors is string", colors: "blue,red" }
1 của tài liệu gốc, tất nhiên được sao chép vào mọi tài liệu được sản xuất bởi $unwind
. Khi chúng tôi quay lại "khóa chung" này như một tài liệu duy nhất, chúng tôi có thể "đếm" "tài liệu" còn lại được trích xuất từ mảng bằng bộ tích lũy { "$group": {
"_id": "$_id",
"Array": { "$push": "$Array" },
"total": { "$sum": 1 }
}}
6.Nếu chúng tôi muốn trở lại "mảng" còn lại, thì bạn có thể
{ "_id" : 1, "item" : "ABC1", "description" : "product 1", colors: [ "blue", "black", "red" ] } { "_id" : 2, "item" : "ABC2", "description" : "product 2", colors: [ "purple" ] } { "_id" : 3, "item" : "XYZ1", "description" : "product 3", colors: [ ] } { "_id" : 4, "item" : "ZZZ1", "description" : "product 4 - missing colors" } { "_id" : 5, "item" : "ZZZ2", "description" : "product 5 - colors is string", colors: "blue,red" }
4 và xây dựng lại mảng chỉ với các thành viên còn lại: { "$group": {
"_id": "$_id",
"Array": { "$push": "$Array" },
"total": { "$sum": 1 }
}}
Nhưng tất nhiên thay vì sử dụng $size
trong một giai đoạn đường ống khác, chúng ta chỉ có thể "đếm" như chúng ta đã làm với
{ "$group": {
"_id": "$_id",
"Array": { "$push": "$Array" },
"total": { "$sum": 1 }
}}
6 Tài liệu về nhà → Hướng dẫn sử dụng MongoDB → MongoDB Manual
$size
Counts và trả về tổng số mục trong một mảng.Counts and returns the total number of items in an array.
$size
có cú pháp sau: has the following syntax:
Đối số cho $size
có thể là bất kỳ biểu thức nào miễn là nó giải quyết thành một mảng. Để biết thêm thông tin về biểu thức, xem biểu thức.$size
can be any
expression as long as it resolves to an array. For more information on expressions, see Expressions.
Đối số cho $size
phải giải quyết cho một mảng. Nếu đối số cho $size
bị thiếu hoặc không giải quyết được một mảng, $size
lỗi.$size
must resolve to an array. If the argument for $size
is missing or does not resolve to an array,
$size
errors.
Xem xét bộ sưu tập
db.inventory.aggregate[[ { $project: { item: 1, numberOfColors: { $cond: { if: { $isArray: "$colors" }, then: { $size: "$colors" }, else: "NA"} } } } ] ]
3 với các tài liệu sau:{ "_id" : 1, "item" : "ABC1", "description" : "product 1", colors: [ "blue", "black", "red" ] } { "_id" : 2, "item" : "ABC2", "description" : "product 2", colors: [ "purple" ] } { "_id" : 3, "item" : "XYZ1", "description" : "product 3", colors: [ ] } { "_id" : 4, "item" : "ZZZ1", "description" : "product 4 - missing colors" } { "_id" : 5, "item" : "ZZZ2", "description" : "product 5 - colors is string", colors: "blue,red" }
Hoạt động đường ống tổng hợp sau đây sử dụng toán tử $size
để trả về số lượng phần tử trong mảng
db.inventory.aggregate[[ { $project: { item: 1, numberOfColors: { $cond: { if: { $isArray: "$colors" }, then: { $size: "$colors" }, else: "NA"} } } } ] ]
5:$size
operator to return
the number of elements in the db.inventory.aggregate[[ { $project: { item: 1, numberOfColors: { $cond: { if: { $isArray: "$colors" }, then: { $size: "$colors" }, else: "NA"} } } } ] ]
5 array:db.inventory.aggregate[[ { $project: { item: 1, numberOfColors: { $cond: { if: { $isArray: "$colors" }, then: { $size: "$colors" }, else: "NA"} } } } ] ]
Hoạt động trả về như sau:
{ "_id" : 1, "item" : "ABC1", "numberOfColors" : 3 } { "_id" : 2, "item" : "ABC2", "numberOfColors" : 1 } { "_id" : 3, "item" : "XYZ1", "numberOfColors" : 0 } { "_id" : 4, "item" : "ZZZ1", "numberOfColors" : "NA" } { "_id" : 5, "item" : "ZZZ2", "numberOfColors" : "NA" }