Trong MongoDB, $avg
toán tử đường ống tổng hợp tính toán và trả về giá trị trung bình của các giá trị số được chỉ định.
Cú pháp
$avg
toán tử hỗ trợ hai cú pháp.
Cú pháp 1:
{ $avg: <expression> }
Cú pháp 2:
{ $avg: [ <expression1>, <expression2> ... ] }
Cú pháp đầu tiên chấp nhận một đối số và cú pháp thứ hai chấp nhận nhiều đối số.
Khi được sử dụng trong nhóm $group
giai đoạn này, bạn chỉ có thể sử dụng cú pháp đầu tiên. Trong trường hợp này, $avg
trả về giá trị trung bình chung của tất cả các giá trị số là kết quả của việc áp dụng một biểu thức được chỉ định cho mỗi tài liệu trong một nhóm tài liệu chia sẻ cùng một nhóm theo khóa.
Ví dụ về Cú pháp 1 (Đối số Đơn)
Dưới đây là một số ví dụ sử dụng cú pháp 1.
Tài liệu được Nhóm
Ví dụ này sử dụng $avg
kết hợp với $group
để trả về giá trị trung bình trên một nhóm tài liệu được nhóm theo khóa.
Giả sử chúng ta có một bộ sưu tập có tên là pets
với các tài liệu sau:
{"_id":1, "name":"Wag", "type":"Dog", "weight":20} {"_id":2, "name":"Bark", "type" :"Dog", "weight":10} {"_id":3, "name":"Meo meo", "type":"Cat", "weight":7} {"_id":4, "name" :"Scratch", "type":"Cat", "weight":8} {"_id":5, "name":"Bruce", "type":"Kangaroo", "weight":100} {" _id ":6," name ":" Hop "," type ":" Kangaroo "," weight ":130} {" _id ":7," name ":" Punch "," type ":" Kangaroo ", "weight":200} {"_id":8, "name":"Snap", "type":"Cat", "weight":12} {"_id":9, "name":"Ruff", "type":"Dog", "weight":30}
Chúng tôi có thể nhóm các tài liệu này theo type
của chúng và sau đó sử dụng $avg
để trả về trọng lượng trung bình của mỗi nhóm:
db.pets.aggregate(
[
{
$group:
{
_id: "$type",
average_weight: { $avg: "$weight" }
}
}
]
)
Kết quả:
{"_id":"Dog", "average_weight":20} {"_id":"Cat", "average_weight":9} {"_id":"Kangaroo", "average_weight":143.33333333333334}Mảng
Ví dụ này áp dụng
$avg
vào một tài liệu duy nhất có chứa một trường với một mảng giá trị.Tùy chọn này chỉ khả dụng khi sử dụng cú pháp đối số duy nhất. Mảng bị bỏ qua khi sử dụng cú pháp nhiều đối số (thông tin thêm về điều này bên dưới).
Giả sử chúng ta có một bộ sưu tập có tên là
players
với các tài liệu sau:{"_id":1, "player":"Homer", "score":[1, 7, 2, 3, 8, 7, 1]} {"_id":2, "player":" Marge "," điểm ":[0, 1, 8, 17, 18, 8]} {" _id ":3," player ":" Bart "," score ":[15, 11, 8, 0, 1 , 3]} {"_id":4, "player":"Brian", "Score":[7]} {"_id":5, "player":"Farnsworth", "Score":[]} { "_id":6, "player":"Meg", "score":null} {"_id":7, "player":"Ron"}Chúng tôi có thể áp dụng
$avg
đến điểmscores
trường trong mỗi tài liệu:db.players.aggregate( [ { $project: { player: 1, averageScore: { $avg: "$scores" } } } ] )
Kết quả:
{"_id":1, "player":"Homer", "averageScore":4.142857142857143} {"_id":2, "player":"Marge", "averageScore":8.666666666666666} {"_id":3, "player":"Bart", "averageScore":6.333333333333333} {"_id":4, "player":"Brian", "averageScore":7} {"_id":5, "player":"Farnsworth "," averageScore ":null} {" _id ":6," player ":" Meg "," averageScore ":null} {" _id ":7," player ":" Ron "," averageScore ":null}Trong trường hợp này, bốn tài liệu đầu tiên trả về giá trị trung bình của các số khác nhau trong các mảng tương ứng của chúng.
Trong trường hợp của tài liệu 4, số này giống với số vì chỉ có một số trong mảng.
Tài liệu 5 được trả về
null
vì chúng tôi đã cung cấp một mảng trống.Tài liệu 6 trả về
null
bởi vì chúng tôi đã cung cấpnull
như đối số.Tài liệu 7 trả về
null
bởi vì trường thậm chí không tồn tại.Ví dụ về Cú pháp 2 (Nhiều đối số)
Cú pháp thứ hai liên quan đến việc cung cấp
$avg
với nhiều hơn một đối số.$avg
sau đó tính giá trị trung bình dựa trên tất cả các đối số được cung cấp.Giả sử chúng ta có một tập hợp được gọi là
data
với các tài liệu sau:{"_id":1, "a":1, "b":2, "c":3, "d":4} {"_id":2, "a":1, "b" :2, "c":3, "d":[4]} {"_id":3, "a":1, "b":2, "c":3, "d":"Này"} {"_id":4, "a":"Một", "b":"Hai", "c":"Ba", "d":"Bốn"}Chúng tôi có thể sử dụng
$avg
để trả về giá trị trung bình củaa
,b
,c
vàd
các trường của mỗi tài liệu:db.data.aggregate( [ { $project: { avg: { $avg: [ "$a", "$b", "$c", "$d" ] } } } ] )
Kết quả:
{"_id":1, "avg":2.5} {"_id":2, "avg":2} {"_id":3, "avg":2} {"_id":4, " trung bình ":null}Tài liệu 1 trả về giá trị trung bình của các giá trị đầu vào của
1
,2
,3
và4
.Tuy nhiên, hai tài liệu tiếp theo chỉ trả về giá trị trung bình của các giá trị đầu vào của
1
,2
và3
.$avg
toán tử đã bỏ quad
của họ lĩnh vực.Điều này là do
$avg
bỏ qua các giá trị không phải số. Vì vậy, trong trường hợp này, nó đã bỏ qua"Hey"
trong tài liệu 3 và tính giá trị trung bình từ các trường (số) còn lại.Đối với tài liệu 2,
d
của nó trường chứa một mảng. Như đã đề cập,$avg
toán tử bỏ qua mảng khi sử dụng cú pháp nhiều đối số. Chính xác hơn, nó coi các mảng là các giá trị không phải số khi được sử dụng trong ngữ cảnh này và$avg
bỏ qua các giá trị không phải số.Nếu tất cả các giá trị không phải là số, thì
$avg
trả vềnull
. Chúng ta có thể thấy điều này với tài liệu 4.Các trường bị thiếu
Khi sử dụng cú pháp nhiều đối số,
$avg
bỏ qua bất kỳ trường nào bị thiếu. Có nghĩa là, nếu bạn cung cấp một trường không tồn tại, nó sẽ bỏ qua nó. Nếu không có trường nào tồn tại, thì nó trả vềnull
.Ví dụ:
db.data.aggregate( [ { $project: { avg: { $avg: [ "$a", "$b", "$c", "$d", "$e" ] } } } ] )
Kết quả:
{"_id":1, "avg":2.5} {"_id":2, "avg":2} {"_id":3, "avg":2} {"_id":4, " trung bình ":null}Trong trường hợp này, tôi đã cung cấp thêm một trường (
$e
) không tồn tại trong tài liệu.$avg
đã tính giá trị trung bình dựa trên các trường còn lại do tồn tại.Tuy nhiên, đây là những gì sẽ xảy ra khi không có trong số các trường tồn tại:
db.data.aggregate( [ { $project: { result: { $avg: [ "$x", "$y", "$z" ] } } } ] )
Kết quả:
{"_id":1, "result":null} {"_id":2, "result":null} {"_id":3, "result":null} {"_id":4, " kết quả ":null}Kết quả là
null
cho tất cả các tài liệu.Như chúng ta đã thấy trước đó, khi sử dụng cú pháp một đối số, một trường bị thiếu dẫn đến
null
.Ví dụ:
db.pets.aggregate( [ { $group: { _id: "$type", avg: { $avg: "$oops!" } } } ] )
Kết quả:
{"_id":"Kangaroo", "avg":null} {"_id":"Cat", "avg":null} {"_id":"Dog", "avg":null}Các giai đoạn có sẵn
$avg
có sẵn trong các giai đoạn sau:
-
$group
-
$project
-
$addFields
-
$set
-
$replaceRoot
-
$replaceWith
-
$match
giai đoạn bao gồm$expr
biểu hiện