Hoàn toàn có thể nếu sử dụng MongoDB 3.6 và mới hơn thông qua khung tổng hợp. Sử dụng $objectToArray
toán tử trong một đường ống tổng hợp để chuyển đổi tài liệu thành một mảng. Mảng trả về chứa một phần tử cho mỗi cặp trường / giá trị trong tài liệu gốc. Mỗi phần tử trong mảng trả về là một tài liệu chứa hai trường k
và v
.
Tham chiếu tới root tài liệu có thể thực hiện được thông qua $$ROOT
biến hệ thống tham chiếu đến tài liệu cấp cao nhất hiện đang được xử lý trong giai đoạn tổng hợp.
Khi lấy mảng, bạn có thể tận dụng việc sử dụng $addFields
bước đường ống để tạo một trường chứa số lượng và số lượng thực tế được lấy bằng cách sử dụng $size
nhà điều hành.
Tất cả điều này có thể được thực hiện trong một đường dẫn duy nhất bằng cách lồng các biểu thức như sau:
db.collection.aggregate([
{ "$addFields": {
"count": {
"$size": {
"$objectToArray": "$$ROOT"
}
}
} }
])
Đầu ra mẫu
{
"_id" : ObjectId("5a7cd94520a31e44e0e7e282"),
"a" : 1.0,
"b" : 1.0,
"c" : 2.0,
"z" : 2.0,
"count" : 5
}
Để loại trừ _id
, bạn có thể sử dụng $filter
toán tử như:
db.collection.aggregate([
{
"$addFields": {
"count": {
"$size": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": { "$ne": [ "$$el.k", "_id" ] }
}
}
}
}
}
])
hoặc theo đề xuất của 0zkr PM, chỉ cần thêm một $project
bước đường ống ở đầu:
db.collection.aggregate([
{ "$project": { "_id": 0 } },
{ "$addFields": {
"count": {
"$size": {
"$objectToArray": "$$ROOT"
}
}
} }
])