sql >> Databáze >  >> NoSQL >> MongoDB

Jak tlačit na pole MongoDB pomocí AngularJS?

Je zde pár věcí, které nejsou skvělé, ale nejprve pokrývají základy a rozběhnou vás.

První věcí je opravit metodu volající úhlovou stranu služby. Koncový bod API rozhodně neočekává syntaxi aktualizace MongoDB, kterou používáte, ale spíše jen objekt. Nejprve to tedy opravte:

$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);
    });
}

Nyní má váš konec API serveru nějaké chyby, upřednostnil bych totální redesign, ale s nedostatkem informací se soustředím pouze na vyřešení hlavních problémů, aniž by se hodně změnily.

Za předpokladu, že se jedná o lodash knihovna, .merge() funkce je zde implementována nesprávně. Je třeba říci, jak správně „zacházet“ s obsahem pole ve „sloučení“ a v současnosti je nejlepší, co se stane, „přepsání“. Dáme tomu trochu chytrosti:

// 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);
    });
  });
};`

Má to ale háček, protože se pouze „připojí“ k poli. Pokud tedy do svého vstupu vložíte něco, co tam již bylo, budou přidány původní položky i cokoli ze vstupu pole.

Vypořádat se s tím je zcela jiný problém, který je třeba vyřešit v závislosti na vašich potřebách.

Z mého vlastního pohledu bych pole poslal tam, kde je to možné, a měl bych koncový bod, který je „pouze“ pro připojení k poli dokumentu, spíše než „obecnou“ aktualizaci dokumentu, jakou máte zde.

To vám umožní lépe využívat funkce aktualizace MongoDB podle očekávaných akcí. Takže něco takového v servisním volání:

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

A na konci API serveru:

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);
     }
  );
};

Takže to jednoduše vezme tělo "komentáře" a připojí ho k poli. A co je nejdůležitější, dělá to "atomicky", takže žádný jiný možný požadavek nemůže kolidovat při provádění něčeho podobného, ​​jako dělá současné "sloučení". Ostatní požadavky na stejný koncový bod se pouze „připojí“ k poli v aktuálním stavu, ve kterém byl požadavek vytvořen, a stejně tak bude i toto.

To je to, co $push operátor je pro, takže je rozumné jej používat.

Něco k zamyšlení.




  1. Použití Async s MongoDb k vyplnění dokumentů sbírky v pořadí

  2. Vztah Mongodb 1to1 mezi vnořenými dokumenty

  3. MongoDB na DynamoDB

  4. Jarní setkání s MongoDB