#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()
}
}
]
)