1

MongoDB コレクションに到達できず、複雑なドキュメントの値を変更できませんでした。以下に示す 1 つの例よりも多くのバリエーション、あらゆる種類のバリエーションを試しましたが、失敗します。

Key「air」のValueを「rain」から「clear」に変更したいです。実生活では、キー「空気」の現在の値が「雨」であることはわかりません。

私は MongoDB _id オブジェクトを使用していないことに注意してください。これを使用せずにこれを達成したいと考えています。

weatherSys コレクションの 3 つのドキュメント:

    {
    "_id" : ObjectId("58a638fb1831c61917f921c5"),
    "SanFrancisco" : [
        { "sky" : "grey" },
        { "air" : "rain" },
        { "ground" : "wet" }
      ]
    }
    {
    "_id" : ObjectId("58a638fb1831c61917f921c6"),
    "LosAngeles" : [
        { "sky" : "grey" },
        { "air" : "rain" },
        { "ground" : "wet" }
      ]
    }
    {
    "_id" : ObjectId("58a638fb1831c61917f921c7"),
    "SanDiego" : [
        { "sky" : "grey" },
        { "air" : "rain" },
        { "ground" : "wet" }
      ]
    }

var docKey   = "LosAngeles";
var subKey   = "air";
var newValue = "clear";

var query       = {};
//var queryKey  = docKey + ".$";  
query[query]    = subKey;                    // query = { }

var set     = {};
var setKey  = docKey + ".0." + subKey;
set[setKey] = newValue;                      // set = { "weather.0.air" : "clear" }

db.collection('weatherSys').update(query, { $set: set }, function(err, result) {
  if (err) throw err;
});

更新-1: わかりました。あなたが提案したよりも少し単純なレイアウトを見つけられることを望んでいましたが、失敗しました。私が試したことはすべて、「空中」キーレベルではアドレス指定できませんでした。だから私はあなたの正確なJSONを私のコレクションにコピーして貼り付けて実行しました。コレクションの操作とテストに MongoChef を使用しています。

これは、JSON を 3 回貼り付けて 3 つのドキュメントを作成した新しいレイアウトです。

ここに画像の説明を入力

次に、「サンフランシスコ」ドキュメントの「air」キーを更新しようとしたところ、予期しない結果が得られました。"air":"dry" を更新するのではなく、"San Francisco" オブジェクトに新しい "air" キーを作成しました。

ここに画像の説明を入力

だから私は大丈夫だと思ったので、更新をもう一度試して、何が起こるか見てみましょう:

ここに画像の説明を入力

ここに画像の説明を入力

ご覧のとおり、以前に作成した「air」キーが更新されました。私はこれと戦って「私の」方法で機能させようとすることができましたが、それを機能させたいだけなので、「機能している」ものに沿ってコレクションのレイアウトを再構成します。

ここに画像の説明を入力

そして、更新を再度実行します。

ここに画像の説明を入力

次に、更新を再度実行して確認します。

ここに画像の説明を入力

動作します。マルチドキュメント環境で適切に更新しています。だから、これは私の現在の作業コレクションのレイアウトです:

ここに画像の説明を入力

ここに画像の説明を入力

これについていくつか質問があります-

  1. すべてのドキュメントで最上位のキー「天気」を使用しています。ドキュメント内の情報には何も追加しません。そのキーとそれがもたらすオーバーヘッドを必要としないレイアウト設計の変更はありますか?

  2. 「天気」キーを使用する必要があるとしましょう。その値は配列ですが、その配列には、都市、空、空気、および地面のキーを含むオブジェクトという 1 つの要素しかありません。アドレス指定では、要素が 1 つだけの配列を使用する必要がありますか? それとも、私はそれを取り除くことができますか?"weather":[{}] の代わりに "weather":{} を設計することはできますか? または、アドレス指定できない問題が再び発生するのでしょうか?

  3. キーの値のいずれかを update() できるようになりました: 空、空、地面ですが、ドキュメントの 1 つでキー「地面」の値を読み取ると言う find() 構造は何ですか?

----> OK、私はこの質問を持っていると思います #3- db.weatherSys.find({ "weather.city" : "San Francisco" }, { "weather.ground": 1 })

  1. あなたが提案した元のコレクション レイアウトで、あなたと私が期待したように更新されず、代わりに新しい「都市」オブジェクトを作成した理由を説明してもらえますか?

ここにたくさん。ご愛顧いただきありがとうございます。

4

1 に答える 1