В MongoDB, $stdDevSamp
Операторът на конвейера за агрегация изчислява стандартното отклонение на извадката на входните стойности.
Входните стойности могат да бъдат от група документи (т.е. документи, които са групирани по един и същ ключ) или могат да бъдат множество полета в рамките на един документ.
$stdDevSamp
е подобен на $stdDevPop
. Разликата е, че $stdDevSamp
изчислява извадката стандартно отклонение, докато $stdDevPop
изчислява населението стандартно отклонение.
Затова използвайте $stdDevSamp
ако вашите стойности обхващат извадка от съвкупност от данни, от които да обобщите популацията. Ако стойностите представляват цялата популация от данни или не искате да обобщавате за по-голяма популация, използвайте $stdDevPop
вместо това.
Синтаксис
$stdDevSamp
операторът поддържа два синтаксиса.
Синтаксис 1:
{ $stdDevSamp: <expression> }
Синтаксис 2:
{ $stdDevSamp: [ <expression1>, <expression2> ... ] }
Първият синтаксис приема един аргумент, а вторият синтаксис приема множество аргументи.
Когато се използва в $group
етап, можете да използвате само първия синтаксис. В този случай $stdDevSamp
връща примерното стандартно отклонение на посочения израз за група документи, които споделят една и съща група по ключ.
Примери за синтаксис 1 (единичен аргумент)
Ето няколко примера, които използват синтаксис 1.
Групирани документи
Този пример използва $stdDevSamp
във връзка с $group
за да върнете примерното стандартно отклонение в група документи, които са групирани по ключ.
Да предположим, че имаме колекция, наречена stonks
със следните документи:
{ "_id" : 1, "ticker" : "gme", "price" : 10 } { "_id" : 2, "ticker" : "gme", "price" : 40 } { "_id" : 3, "ticker" : "gme", "price" : 90 } { "_id" : 4, "ticker" : "gme", "price" : 180 } { "_id" : 5, "ticker" : "gme", "price" : 290 } { "_id" : 6, "ticker" : "gme", "price" : 390 } { "_id" : 7, "ticker" : "gme", "price" : 190 } { "_id" : 8, "ticker" : "gme", "price" : 90 } { "_id" : 9, "ticker" : "gme", "price" : 10 } { "_id" : 10, "ticker" : "jnj", "price" : 131 } { "_id" : 11, "ticker" : "jnj", "price" : 133 } { "_id" : 12, "ticker" : "jnj", "price" : 138 } { "_id" : 13, "ticker" : "jnj", "price" : 141 } { "_id" : 14, "ticker" : "jnj", "price" : 145 } { "_id" : 15, "ticker" : "jnj", "price" : 150 } { "_id" : 16, "ticker" : "jnj", "price" : 154 } { "_id" : 17, "ticker" : "jnj", "price" : 156 } { "_id" : 18, "ticker" : "jnj", "price" : 160 }
Можем да групираме тези документи по техния ticker
поле и след това използвайте $stdDevSamp
за връщане на примерното стандартно отклонение на price
поле за всяка група:
db.stonks.aggregate(
[
{
$group:
{
_id: "$ticker",
result: { $stdDevSamp: "$price" }
}
}
]
)
Резултат:
{ "_id" : "gme", "result" : 131.24404748406687 } { "_id" : "jnj", "result" : 10.344080432788612 }
Можем да видим, че gme
има много по-високо стандартно отклонение на извадката от jnj
.
Масиви
Този пример се прилага $stdDevSamp
към един документ, който съдържа поле с масив от стойности.
Тази опция е налична само при използване на синтаксис на единичен аргумент. Масивите се игнорират, когато се използва синтаксисът с няколко аргумента (повече за това по-долу).
Да предположим, че имаме колекция, наречена players
със следните документи:
{ "_id" : 1, "player" : "Homer", "scores" : [ 1, 7, 2, 3, 8, 7, 1 ] } { "_id" : 2, "player" : "Marge", "scores" : [ 0, 1, 8, 17, 18, 8 ] } { "_id" : 3, "player" : "Bart", "scores" : [ 15, 11, 8, 0, 1, 3 ] } { "_id" : 4, "player" : "Brian", "scores" : [ 7 ] } { "_id" : 5, "player" : "Farnsworth", "scores" : [ ] } { "_id" : 6, "player" : "Meg", "scores" : null }
Можем да приложим $stdDevSamp
към scores
поле във всеки документ:
db.players.aggregate(
[
{
$project:
{
result: { $stdDevSamp: "$scores" }
}
}
]
)
Резултат:
{ "_id" : 1, "result" : 3.0783421635988546 } { "_id" : 2, "result" : 7.633260552782583 } { "_id" : 3, "result" : 5.988878581726855 } { "_id" : 4, "result" : null } { "_id" : 5, "result" : null } { "_id" : 6, "result" : null }
В този случай първите три документа върнаха стандартното отклонение на извадката за различните числа, които бяха в съответните им масиви.
Документ 4 доведе до стандартно отклонение от null
. Това е така, защото предоставихме само едно число в масива. Ако използвахме $stdDevPop
, това би върнало 0
.
Документ 5 върна null
защото предоставихме празен масив.
Документ 6 върна null
защото предоставихме null
като аргумент.
Пример за синтаксис 2 (множество аргументи)
Вторият синтаксис включва предоставяне на $stdDevSamp
с повече от един аргумент. $stdDevSamp
след това изчислява стандартното отклонение въз основа на всички предоставени аргументи.
Да предположим, че имаме колекция, наречена data
със следните документи:
{ "_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" : "Hey" }
Можем да използваме $stdDevSamp
за връщане на примерното стандартно отклонение на a
, b
, c
и d
полета на всеки документ:
db.data.aggregate(
[
{
$project:
{
result: { $stdDevSamp: [ "$a", "$b", "$c", "$d" ] }
}
}
]
)
Резултат:
{ "_id" : 1, "result" : 1.2909944487358056 } { "_id" : 2, "result" : 1 } { "_id" : 3, "result" : 1 }
Резултатът от първия документ се основава на входните стойности на 1
, 2
, 3
и 4
.
Последните два документа обаче доведоха само до 1
, 2
и 3
се оценява. $stdDevSamp
операторът игнорира техния d
полета.
$stdDevSamp
игнорира нечислови стойности. Така че в този случай той игнорира "Hey"
в документ 3 и изчислява стандартното отклонение на извадката от останалите (числови) полета.
Що се отнася до документ 2, неговият d
полето съдържа масив. Както споменахме, $stdDevSamp
операторът игнорира масиви, когато използва синтаксис с няколко аргумента. По-точно, той третира масивите като нечислови стойности, когато се използва в този контекст. И както споменахме, $stdDevSamp
игнорира нечислови стойности.
Ако всички стойности не са числови, тогава $stdDevSamp
връща null
.
Липсващи полета
Когато използвате синтаксиса с множество аргументи, $stdDevSamp
игнорира всички липсващи полета. Тоест, ако предоставите поле, което не съществува, то го игнорира. Ако нито едно от полетата не съществува, то връща null
.
Пример:
db.data.aggregate(
[
{
$project:
{
result: { $stdDevSamp: [ "$a", "$b", "$c", "$d", "$e" ] }
}
}
]
)
Резултат:
{ "_id" : 1, "result" : 1.2909944487358056 } { "_id" : 2, "result" : 1 } { "_id" : 3, "result" : 1 }
В този случай предоставих допълнително поле ($e
), който не съществува в документа. $stdDevSamp
изчисли стандартното отклонение на извадката въз основа на останалите полета, които правят съществуват.
Но ето какво се случва, когато няма от полетата съществуват:
db.data.aggregate(
[
{
$project:
{
result: { $stdDevSamp: [ "$x", "$y", "$z" ] }
}
}
]
)
Резултат:
{ "_id" : 1, "result" : null } { "_id" : 2, "result" : null } { "_id" : 3, "result" : null }
Резултатът е null
за всички документи.
Когато се използва синтаксисът с един аргумент, липсващо поле води до null
.
Пример:
db.stonks.aggregate(
[
{
$group:
{
_id: "$ticker",
result: { $stdDevSamp: "$oops!" }
}
}
]
)
Резултат:
{ "_id" : "gme", "result" : null } { "_id" : "jnj", "result" : null }
Налични етапи
$stdDevSamp
е наличен в следните етапи:
$group
$project
$addFields
$set
$replaceRoot
$replaceWith
$match
етап, който включва$expr
израз