1

ドキュメントからサブオブジェクト 'りんご' を削除し、'fruitInventory' プロパティを更新して、りんごの量だけ減らしようとしています。

どのように進めればよいかわかりません。ドット表記を使用するか、リンゴの全文検索を行うべきですか? これが問題かどうかはわかりませんが、リンゴは常にフィールド 1 にあると想定できます。

// Document 1 
{
    "1": {
        "apples": 3,
        "fruitInventory": 21,
        "oranges": 12,
        "kiwis": 3,
        "lemons": 3
    },
    "2": {
        "bananas": 4,
        "fruitInventory": 12,
        "oranges": 8,
    },
    "_id": "1"
}

// Document 2
{
    "1": {
        "apples": 5,
        "fruitInventory": 10,
        "oranges": 2,
        "pears": 3
    },
    "2": {
        "bananas": 4,
        "fruitInventory": 6,
        "cherries": 2,
    },
    "_id": "2"
}

結果は次のようになります。

// Document 1 
{
    "1": {
        "fruitInventory": 18,
        "oranges": 12,
        "kiwis": 3,
        "lemons": "3"
    },
    "2": {
        "bananas": 4,
        "fruitInventory": 12,
        "oranges": 8,
    },
    "_id": "1"
}

// Document 2
{
    "1": {
        "fruitInventory": 5,
        "oranges": "2",
        "pears": "3"
    },
    "2": {
        "bananas": 4,
        "fruitInventory": 6,
        "cherries": 2,
    },
    "_id": "2"
}

よろしくお願いします。

4

3 に答える 3

2

MongoDB クエリ言語では、ドキュメントの情報を使用してドキュメントを更新する方法はありません。つまり、あるプロパティを別のプロパティの値でインクリメントする方法はありません。具体的に言うと、 Xをアトミック操作としてプロパティfruitInventoryの値として X でインクリメントする方法はありません。apples

競合を回避しながらこれを実装する方法は、2 つのfindAndModify操作を使用することです (Mongo シェル構文でここに表示されます)。

var fruit = db.fruit.findAndModify({
 query: {locked: {$ne: true}, "1.apples": {$exists: true}},
 update: {$set: {locked: true}}
});

var fruitInventory = fruit["1"]["fruitInventory"];
var apples = fruit["1"]["apples"];

db.fruit.findAndModify({
  query: {"_id": fruit["_id"]},
  update: {
    $set: {"1.fruitInventory": fruitInventory + apples}, 
    $unset: {locked: false, "1.apples": true}
  }
});

まず、ロックされていない (これについては後で説明します)1.applesプロパティを持つドキュメントを見つけます。ドキュメントが返されて更新さlockedれ、単一のアトミック操作としてプロパティが取得されます。ドキュメントにはlockedプロパティが含まれているため、同じクエリでは検出されないため、同じドキュメントを 2 回変更するリスクなしに、このクエリを複数回並行して実行できます。

1.fruitInventory次にandを抽出して1.apples、次の式を簡略化します。

2 番目は、プロパティを新しい合計でfindAndModify更新し、プロパティとプロパティの設定を解除します (ドキュメントを以前のロックされていない状態に戻すため)。1.fruitInventory1.appleslocked

findAndModifyすべてのドキュメントを更新するには、最初のコードが戻るまでnull(クエリに一致するドキュメントがないことを意味します)、このコードを何度も実行する必要があります。

于 2010-12-31T11:09:52.040 に答える
1

マルチアップデートで $unset を使用します。

> db.whatever.update({}, {$unset : {"1.apples" : true}}, false, true)

より高度な注意点として、より豊富なデータ型を使用することをお勧めします (たとえば、int は、正当な理由がない限り、通常は int として格納する必要があります)。

于 2010-12-25T03:26:02.157 に答える
0

MongoDB では、ドキュメントの既存のスキームを変更することはできません。このタスクでは、ドキュメント (またはセットの要素) を削除する必要があります。新しい変更されたドキュメント(またはセットの要素)を挿入します

于 2011-01-02T17:43:44.010 に答える