MongoDBでは、$rand
集計パイプライン演算子は、0から1までのランダムな浮動小数点数を返します。
浮動小数点値は、小数点以下17桁までです。末尾のゼロはすべて削除されるため、桁数は異なる場合があります。
$rand
演算子はMongoDB4.4.2で導入されました。
例
cats
というコレクションがあるとします。 次のドキュメントを使用:
{ "_id" : 1, "name" : "Scratch" } { "_id" : 2, "name" : "Meow" } { "_id" : 3, "name" : "Fluffy" }
$rand
を使用できます 猫ごとにランダムな数字を生成する演算子:
db.cats.aggregate(
[
{
$project:
{
randomNumber: { $rand: {} }
}
}
]
)
結果:
{ "_id" : 1, "randomNumber" : 0.5593964875463812 } { "_id" : 2, "randomNumber" : 0.04357301703691149 } { "_id" : 3, "randomNumber" : 0.7556877215199272 }
$rand
演算子は引数を受け入れません。$rand: {}
を使用して呼び出すだけです。 。
また、$rand
呼び出されるたびに新しい番号を生成します。したがって、上記のコードを複数回実行すると、猫ごとに異なるランダムな番号が生成されます。
これを示すために、もう一度実行します。新しい結果は次のとおりです。
{ "_id" : 1, "randomNumber" : 0.19672627212049873 } { "_id" : 2, "randomNumber" : 0.05513133909795318 } { "_id" : 3, "randomNumber" : 0.7509841462815067 }
ランダムな数字は前の例で生成されたものとは異なることがわかります。
1より大きいランダムな数値
前述のように、$rand
0から1までのランダムな浮動小数点数を返します。これは、ゼロを取得してもかまわない場合は問題ありません。その後に、小数点以下17桁までのランダムな桁が続きます。
しかし、1より大きいランダムな数が必要な場合はどうなりますか?
このような場合、$multiply
を使用できます $rand
の結果を乗算する演算子 。
例:
db.cats.aggregate(
[
{
$project:
{
randomNumber: { $multiply: [ { $rand: {} }, 10 ] }
}
}
]
)
結果:
{ "_id" : 1, "randomNumber" : 1.958938543288535 } { "_id" : 2, "randomNumber" : 4.437057321655847 } { "_id" : 3, "randomNumber" : 8.238909118372334 }
ランダム整数
小数部分も廃止したい場合があります。この場合、$floor
などの演算子を使用できます。 小数点部分を削除して、整数を残します。
例:
db.cats.aggregate(
[
{
$project:
{
name: 1,
randomNumber: {
$floor: {
$multiply: [ { $rand: {} }, 10 ]
}
}
}
}
]
)
結果:
{ "_id" : 1, "name" : "Scratch", "randomNumber" : 0 } { "_id" : 2, "name" : "Meow", "randomNumber" : 5 } { "_id" : 3, "name" : "Fluffy", "randomNumber" : 7 }
ここでも同じですが、今回は100を掛けます:
db.cats.aggregate(
[
{
$project:
{
name: 1,
randomNumber: {
$floor: {
$multiply: [ { $rand: {} }, 100 ]
}
}
}
}
]
)
結果:
{ "_id" : 1, "name" : "Scratch", "randomNumber" : 18 } { "_id" : 2, "name" : "Meow", "randomNumber" : 62 } { "_id" : 3, "name" : "Fluffy", "randomNumber" : 92 }
結果を保存する
前述のように、$rand
呼び出されるたびに新しいランダムフロートを生成します。コードを実行するたびに新しいランダム番号が必要な場合はこれで問題ありませんが、各ドキュメントにランダム番号を保存する場合はどうでしょうか。
ドキュメントにランダムな数値を保存するには、$addFields
を使用できます。 演算子(またはそのエイリアス$set
)ドキュメントに新しいフィールドを追加します。
例:
db.cats.aggregate(
[
{ $set: { randomNumber: { $multiply: [ { $rand: {} }, 100 ] } } },
{ $set: { randomNumber: { $floor: "$randomNumber" } } },
{ $merge: "cats" }
]
)
この例では、操作を2つの$set
に分けています。 ステージと$merge
ステージ。
$merge
stageは、集約パイプラインの結果を指定されたコレクションに書き込みます。これは、パイプラインの最後のステージである必要があります。
そのコレクションからドキュメントを返すとき(たとえば、find()
のようなメソッドを使用して )、各ドキュメントに乱数の新しいフィールドが含まれていることがわかります:
db.cats.find()
結果:
{ "_id" : 1, "name" : "Scratch", "randomNumber" : 61 } { "_id" : 2, "name" : "Meow", "randomNumber" : 86 } { "_id" : 3, "name" : "Fluffy", "randomNumber" : 73 }
これで、乱数は永続的になります。ドキュメントは何度でも返却でき、乱数は同じままです。
find()
を実行してみましょう もう一度:
db.cats.find()
結果:
{ "_id" : 1, "name" : "Scratch", "randomNumber" : 61 } { "_id" : 2, "name" : "Meow", "randomNumber" : 86 } { "_id" : 3, "name" : "Fluffy", "randomNumber" : 73 }
まったく同じランダムな数字。