Обновление Mongodb с помощью $ push

#mongodb #mongoose

#mongodb #mongoose

Вопрос:

Мне интересно, возможно ли сделать следующее, но вместо findOne мы используем updateOne?

Нам нужно указать последнее сохраненное местоположение "location":{'coordinates':[ query.long, query.lat]}

в массив прошлых местоположений. {"past_location":array}

Я понимаю, что я мог бы написать что-то вроде

 document = $collection->findOne({"UUID": query.uuid});

if (null !== $document) {
    $collection->update(
        {'_id' => new MongoId($data['id'])),
        {
            '$set':{
     "location":{'coordinates':[ query.long, query.lat]}
    }},
            '$push' => array{
                'past_versions' => {
                    $document.location}
                },
            },
        }
    };
}
  

Но я чувствую, что это просто добавило бы ненужный код в наш updateOne (учитывая, что у нас уже есть вся информация до сохранения / обновления?
Причина в том, что мы уже используем updateOne.

Наш код местоположения:

 /* GRAB URL */
    query = require('url').parse(req.url,true).query;
    if(!query.uuid){
        res.end();
    }

    const llocation = require('mongoose').model('listenerlocation');
    



    const userData = {"UUID": query.uuid};

    var update = {'$set':{
     "location":{'coordinates':[ query.long, query.lat]}
    }};
    options = { upsert: true};
  
    llocation.updateOne(userData, update, options, function(error, result) {
     console.log(result);
     if (!error) {
         // If the document doesn't exist
         if (!result) {
       
        }
     }
     else{
      console.log(error);
     }
    });
  

Итак, в двух словах, я хочу переместить последнее записанное местоположение:

 {"_id":{"$oid":"XXXXXX"},
"UUID":"XXXX-XXXX-XXXX-XXXx-XXXX",
"location":
{"coordinates":[{"$numberDouble":"115.8621"},{"$numberDouble":"-31.9674"}]}
}
  

Это мое решение, но я уверен, что есть лучший способ:

  const userData = {"UUID": query.uuid};

    var document = llocation.findOne({"UUID": query.uuid});
    document.exec(function (err, data) {
        if (err){ 
            //INSERT NEW USER
            var update = {'$set':{
                "location":{'coordinates':[ query.long, query.lat],currentTime: Date.now()}
               }};
               options = { upsert: true};
             
               llocation.updateOne(userData, update, options, function(error, result) {
                console.log(result);
                if (!error) {
                    // If the document doesn't exist
                    if (!result) {
                  
                   }
                }
                else{
                 console.log(error);
                }
               });
               res.json({message:"done"})

               //END NEW USER
        }
        else{
            location = data.location;
            console.log(location);
           // res.json(location)

            /* UPDATE */
                var update = {'$set':{
                "location":{'coordinates':[ query.long, query.lat],currentTime: Date.now()}
               },'$push':{"past_location":data.location}};
               options = { upsert: true};
             
               llocation.updateOne(userData, update, options, function(error, result) {
                console.log(result);
                if (!error) {
                    // If the document doesn't exist
                    if (!result) {
                  
                   }
                }
                else{
                 console.log(error);
                }
               });
               res.json({message:"done"})

            /* END */
        }
        console.log(data);
    });
  

в подмассив, который хранит past_location

Ответ №1:

Вы можете использовать обновление с конвейером агрегации, начиная с MongoDB версии 4.2.2,

 llocation.updateOne(
    { UUID: query.uuid },
    [
        {
            $set: {
                "location.coordinates": [query.long, query.lat],
                past_location: {
                    $concatArrays: [
                        ["$location"], 
                        { $ifNull: ["$past_location", []] }
                    ]
                },
                currentTime: Date.now()
            }
        }
    ]
)