Całkiem możliwe, jeśli używasz MongoDB w wersji 3.6 i nowszej przez platformę agregacji. Użyj $objectToArray
operator w potoku agregacji, aby przekonwertować dokument na tablicę. Zwracana tablica zawiera element dla każdej pary pole/wartość w oryginalnym dokumencie. Każdy element w tablicy zwracanej jest dokumentem zawierającym dwa pola k
i v
.
Odniesienie do rootowania dokumentu jest możliwe dzięki $$ROOT
zmienna systemowa, która odwołuje się do dokumentu najwyższego poziomu, który jest aktualnie przetwarzany na etapie potoku agregacji.
Po pobraniu tablicy możesz wykorzystać $addFields
krok potoku, aby utworzyć pole, które przechowuje liczniki, a rzeczywista liczba jest uzyskiwana za pomocą $size
operatora.
Wszystko to można zrobić w jednym potoku, zagnieżdżając wyrażenia w następujący sposób:
db.collection.aggregate([
{ "$addFields": {
"count": {
"$size": {
"$objectToArray": "$$ROOT"
}
}
} }
])
Przykładowe wyjście
{
"_id" : ObjectId("5a7cd94520a31e44e0e7e282"),
"a" : 1.0,
"b" : 1.0,
"c" : 2.0,
"z" : 2.0,
"count" : 5
}
Aby wykluczyć _id
pole, możesz użyć $filter
operator jako:
db.collection.aggregate([
{
"$addFields": {
"count": {
"$size": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": { "$ne": [ "$$el.k", "_id" ] }
}
}
}
}
}
])
lub zgodnie z sugestią 0zkr PM po prostu dodaj $project
krok potoku na początku:
db.collection.aggregate([
{ "$project": { "_id": 0 } },
{ "$addFields": {
"count": {
"$size": {
"$objectToArray": "$$ROOT"
}
}
} }
])