Bạn không thể làm điều đó như thực tế được tham chiếu trong tài liệu cho $size
. Vì vậy, toán tử đó một mình đánh giá kết quả "theo nghĩa đen" và không thể được sử dụng kết hợp với "toán tử phạm vi" như bạn đang yêu cầu.
Lựa chọn thực sự duy nhất của bạn là yêu cầu "kích thước" "không bằng 0" bằng cách phủ định điều kiện với $not
nhà điều hành. Điều nào hoàn toàn hợp lệ:
db.userStats.count({ "sessions": { "$not": { "$size": 0 } } });
Hoặc nếu không, hãy kiểm tra với phiên bản khác của $size
trong khung tổng hợp, miễn là phiên bản MongoDB của bạn là 2.6 trở lên:
db.userStats.aggregate([
{ "$group": {
"_id": null,
"count": {
"$sum": {
"$cond": [
{ "$gt": [ { "$size": "$sessions", 0 } ] },
1,
0
]
}
}
}}
])
Cũng có thể với $where
hình thức đánh giá JavaScript:
db.userStats.count(function() { return this.sessions.length > 0 });
Nhưng có thể chậm hơn phiên bản trước.
Hoặc trên thực tế, bạn chỉ có thể làm điều này với "ký hiệu dấu chấm" và $exists
nhà điều hành:
db.userStats.count({ "sesssions.0": { "$exists": true } });
Như ý tưởng chung là nếu có một phần tử ở chỉ mục 0
thì mảng có độ dài nào đó.
Tất cả phụ thuộc vào cách tiếp cận của bạn, nhưng bất kỳ hình thức nào trong số này đều mang lại kết quả phù hợp.
Nhưng để có hiệu suất "tốt nhất" từ MongoDB, không sử dụng bất kỳ của các phương pháp này. Thay vào đó, hãy giữ mảng "length" như một thuộc tính của tài liệu bạn đang kiểm tra. Điều này bạn có thể "lập chỉ mục" và các truy vấn được đưa ra thực sự có thể truy cập vào chỉ mục đó, điều mà không cái nào ở trên có thể làm được.
Duy trì nó như thế này:
db.userStats.update(
{ "_id": docId, "sessions": { "$ne": newItem } },
{
"$push": { "sessions": newItem },
"$inc": { "countSessions": 1 }
}
)
Hoặc để loại bỏ:
db.userStats.update(
{ "_id": docId, "sessions": newItem },
{
"$pull": { "sessions": newItem },
"$inc": { "countSessions": -1 }
}
)
Sau đó, bạn có thể chỉ cần truy vấn trên "countSesssions" cũng có thể lập chỉ mục để có hiệu suất tốt nhất:
db.userStats.find({ "countSessions": { "$gt": 0 } })
Và đó là cách "tốt nhất" để làm điều đó.