更新を使用して、実際に問題を解決できます。 メソッドですが、MongoDB 4.2以降を使用している場合は、別の方法で行う必要があります。 2番目のパラメーターは$set
にすることができます 実行する操作またはaggregation
パイプライン。後者を使用すると、データをより自由に形成できます。これはあなたがあなたの問題を解決することができる方法です、私は後で分解します:
db.collection.update({
"cards.advanced.unit": 2
},
[
{
$set: {
"cards.advanced": {
$map: {
input: "$cards.advanced",
as: "adv",
in: {
cards: {
$map: {
input: "$$adv.cards",
as: "advcard",
in: {
$cond: [
{
$eq: [
"$$advcard.id",
"main-2-1"
]
},
{
title: "this is a NEW updated card",
id: "$$advcard.id"
},
"$$advcard"
]
}
}
},
unit: "$$adv.unit"
}
}
}
}
}
],
{
new: true,
});
まず、更新を使用します 3つのパラメータを渡すメソッド:
- フィルタークエリ
- 集約パイプライン
- オプション。ここでは、
new: true
を使用しました 更新されたドキュメントを返し、テストを容易にします。
これが構造です:
db.collection.update({
"cards.advanced.unit": 2
},
[
// Pipeline
],
{
new: true,
});
パイプライン内に必要なのは、$set
という1つのステージだけです。 プロパティadvanced
を置き換える 作成する配列を使用します。
...
[
{
$set: {
"cards.advanced": {
// Our first map
}
}
}
]
...
最初にadvanced
をマッピングします 次の後にネストされたカード配列をマップできるようにする配列:
...
[
{
$set: {
"cards.advanced": {
$map: {
input: "$cards.advanced",
as: "adv",
in: {
// Here we will map the nested array
}
}
}
}
}
]
...
最初のマップで宣言した変数を使用します。この変数には、マップされている高度な配列の現在のアイテムが含まれています(adv
)ネストされた「カード」配列($$adv.cards
)にアクセスしてマップします ):
...
[
{
$set: {
"cards.advanced": {
$map: {
input: "$cards.advanced",
as: "adv",
in: {
cards: {
$map: {
input: "$$adv.cards",
as: "advcard",
in: {
// We place our condition to check for the chosen card here
}
}
},
unit: "$$adv.unit",
}
}
}
}
}
]
...
最後に、現在のカードIDが検索対象のIDと等しいかどうかを確認します$eq: [ "$$advcard.id", "main-2-1" ]
一致する場合は新しいカード、または現在のカードを返却します:
...
{
$cond: [
{
$eq: [
"$$advcard.id",
"main-2-1"
]
},
{
title: "this is a NEW updated card",
id: "$$advcard"
},
"$$advcard"
]
}
...
説明されている内容の実際の例を次に示します。