Nie możesz tego zrobić, ponieważ jest to wskazane w dokumentacji $size
. Tak więc operator sam ocenia wynik „dosłowny” i nie może używaj w połączeniu z „operatorami zasięgu”, takimi jak pytasz.
Jedyną realną opcją jest poproszenie o „rozmiar”, który jest „różny od 0” poprzez zanegowanie warunku za pomocą $not
operator. Co jest całkowicie uzasadnione:
db.userStats.count({ "sessions": { "$not": { "$size": 0 } } });
Lub w inny sposób przetestuj z innym wcieleniem $size
w ramach agregacji, o ile twoja wersja MongoDB to 2.6 lub nowsza:
db.userStats.aggregate([
{ "$group": {
"_id": null,
"count": {
"$sum": {
"$cond": [
{ "$gt": [ { "$size": "$sessions", 0 } ] },
1,
0
]
}
}
}}
])
Być może również z $where
forma oceny JavaScript:
db.userStats.count(function() { return this.sessions.length > 0 });
Ale prawdopodobnie wolniej niż ostatnia wersja.
Lub po prostu możesz to zrobić za pomocą "notacji kropkowej" i $exists
operator:
db.userStats.count({ "sesssions.0": { "$exists": true } });
Ogólna idea jest taka, że jeśli pod indeksem znajduje się element 0
wtedy tablica ma pewną długość.
Wszystko zależy od Twojego podejścia, ale każda z tych form daje właściwy wynik.
Ale aby uzyskać „najlepszą” wydajność MongoDB, nie używaj żadnego tych metod. Zamiast tego zachowaj tablicę "długość" jako właściwość sprawdzanego dokumentu. To możesz "indeksować", a wysłane zapytania mogą faktycznie uzyskać dostęp do tego indeksu, czego żadne z powyższych nie może zrobić.
Utrzymuj to w ten sposób:
db.userStats.update(
{ "_id": docId, "sessions": { "$ne": newItem } },
{
"$push": { "sessions": newItem },
"$inc": { "countSessions": 1 }
}
)
Lub usunąć:
db.userStats.update(
{ "_id": docId, "sessions": newItem },
{
"$pull": { "sessions": newItem },
"$inc": { "countSessions": -1 }
}
)
Następnie możesz po prostu zapytać o „countSesssions”, które mogą również indeksować w celu uzyskania najlepszej wydajności:
db.userStats.find({ "countSessions": { "$gt": 0 } })
I to jest „najlepszy” sposób, aby to zrobić.