sql >> データベース >  >> NoSQL >> MongoDB

AngularJSを使用してMongoDB配列にプッシュする方法は?

    ここには、あまり良くないことがいくつかありますが、最初に基本をカバーして、あなたを動かします。

    まず、サービス角度側を呼び出すメソッドを修正します。 APIエンドポイントは、使用しているMongoDB更新構文ではなく、単なるオブジェクトを確実に期待します。したがって、最初にそれを修正します:

    $scope.saveComment = function(i){
        console.log("id is " + i);
    
        // Split these out so they are easy to log and debug
        var path = '/api/its' + i;
    
        // This must mirror the structure expected in your document for the element
        // Therefore "comments" is represented as an array of objects, even
        // where this is only one.
        var data = { 
           comments: [{ 
             words: $scope.comment,
             userId: $scope.getCurrentUser().name 
           }]
        };
    
        // Call service with response
        $http.put(path,data).success(function(stuff){
          document.location.reload(true);
        });
    }
    

    サーバーAPIエンドにいくつかの障害があります。完全に再設計することをお勧めしますが、情報が不足しているため、ほとんど変更せずに主な問題を修正することに集中しています。

    これがlodash であると仮定します ライブラリ、 .merge() ここでの関数は正しく実装されていません。 「マージ」で配列の内容を適切に「処理」する方法を説明する必要があります。現在、発生する最善の方法は「上書き」です。だから私たちはそれにいくつかの賢さを与えます:

    // Updates an existing it in the DB.
    exports.update = function(req, res) {
      if(req.body._id) { delete req.body._id; }
      It.findById(req.params.id, function (err, it) {
        if (err) { return handleError(res, err); }
        if(!it) { return res.send(404); }
        var updated = _.merge(it, req.body,function(a,b) {
            if (_.isArray(a)) {
                return a.concat(b);    // join source and input
            }
        });
        updated.save(function (err) {
          if (err) { return handleError(res, err); }
          return res.json(200, updated);
        });
      });
    };`
    

    ただし、アレイに「追加」されるだけなので、これには問題があります。したがって、すでに存在する入力に何かを入れると、元のアイテムと配列入力のすべてが追加されます。

    それに対処することは、あなたのニーズに応じて、解決するためのまったく別の問題です。

    私自身の見方からすると、可能な限り配列を送信し、ここにあるような「一般的な」ドキュメントの更新ではなく、ドキュメントの配列に追加するための「ちょうど」エンドポイントを設定します。

    これにより、予想されるアクションごとに、MongoDB更新機能をより有効に活用できます。したがって、サービスコールでは次のようになります:

    // comment can just be a singular object now
    $http.put(path,{ 
        "words": "this that", 
        "userId": 123
    }).success(function(stuff){
    

    そしてサーバーAPI側:

    exports.addComment = function(req, res) {
      if(req.body._id) { delete req.body._id; }
      It.findByIdAndUpdate(req.params.id,
         { "$push": { "comments": req.body } },
         { "new": true },
         function(err,it) {
          if (err) { return handleError(res, err); }
          if(!it) { return res.send(404); }
          return res.json(200, it);
         }
      );
    };
    

    つまり、「コメント」の本文を取得して配列に追加するだけです。最も重要なことは、これを「原子的に」行うため、現在の「マージ」が行っているようなことを行う際に、他の可能な要求が衝突することはありません。同じエンドポイントへの他のリクエストは、リクエストが行われたときと同じように、現在の状態でアレイに「追加」されます。これも同様です。

    これが、 $push 演算子はのためのものなので、それを使用するのが賢明です。

    思考の糧。




    1. コレクションを保存しているときに、MongoDBが長すぎて127バイトの制限を超えるインデックス名を作成しています。これを解決する方法。インデックス作成を無効にできますか?

    2. 流星$pullを配列から削除

    3. MySQLのようなtargzipmongoダンプ

    4. フラスコを起動する前に(起動していない場合は起動して)、redisが実行されているかどうかを確認するにはどうすればよいですか?