Напълно възможно, ако използвате MongoDB 3.6 и по-нова, въпреки рамката за агрегиране. Използвайте $objectToArray
оператор в рамките на конвейер за агрегиране, за да преобразува документа в масив. Връщаният масив съдържа елемент за всяка двойка поле/стойност в оригиналния документ. Всеки елемент в масива за връщане е документ, който съдържа две полета k
и v
.
Препратката към root на документа става възможна чрез $$ROOT
системна променлива, която препраща към документа от най-високо ниво, който в момента се обработва в етапа на конвейера за агрегиране.
След като получите масива, можете да използвате използването на $addFields
стъпка на конвейера, за да създадете поле, което съдържа броя и действителният брой се извлича с помощта на $size
оператор.
Всичко това може да се направи в един тръбопровод чрез влагане на изразите, както следва:
db.collection.aggregate([
{ "$addFields": {
"count": {
"$size": {
"$objectToArray": "$$ROOT"
}
}
} }
])
Примерен изход
{
"_id" : ObjectId("5a7cd94520a31e44e0e7e282"),
"a" : 1.0,
"b" : 1.0,
"c" : 2.0,
"z" : 2.0,
"count" : 5
}
За да изключите _id
поле, можете да използвате $filter
оператор като:
db.collection.aggregate([
{
"$addFields": {
"count": {
"$size": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": { "$ne": [ "$$el.k", "_id" ] }
}
}
}
}
}
])
или както е предложено от 0zkr PM, просто добавете $project
стъпка на конвейера в началото:
db.collection.aggregate([
{ "$project": { "_id": 0 } },
{ "$addFields": {
"count": {
"$size": {
"$objectToArray": "$$ROOT"
}
}
} }
])