Come pubblicare i dati MongoDB nell'array nidificato utilizzando NODE.js ed Express
Ho provato a inviare dati da MongoDB all'utente che ha effettuato l'accesso. Pertanto, ogni volta che un utente attiva una richiesta di invio di dati, dovrebbe essere inviato e annidato sotto quell'utente.
metodo router.post ()
router.post('/savetasks', async (req, res) => {
console.log(req.body);
const { startTime, endTime, elapsedTime } = req.body;
const newTime = new Time({startTime, endTime, elapsedTime});
await newTime.save();
const token = jwt.sign({ _id: newTime._id}, 'secretkey');
res.status(200).json({token});
});
Utilizzando questo metodo posso salvare con successo i dati in MongoDB ma non capisco come ottenerli annidati sotto l'utente specifico.
Dovrebbe essere così:
const userSchema = new Schema({
firstname: String,
lastname: String,
email: String,
password: String,
timings: [{
startTime: String,
endTime: String,
elapsedTime: String
}]
});
Ho provato diversi modi ma tutti mi davano errori. L'unico modo che mi dà più fiducia è in realtà dare il percorso '/ posttasks /: _ id' e assegnare add.function()
ma dato che sono nuovo in Mongo, Express e Node.js non sono riuscito a farlo
Codice angolare
import { Component, OnInit } from '@angular/core';
import { timer, from } from 'rxjs';
import { AuthService} from '../../services/auth.service';
import { TasksService } from '../../services/tasks.service';
import * as moment from 'moment';
import {formatDate} from '@angular/common';
import { Router } from '@angular/router';
@Component({
selector: 'app-private-tasks',
templateUrl: './private-tasks.component.html',
styleUrls: ['./private-tasks.component.css']
})
export class PrivateTasksComponent implements OnInit {
date:Date;
times: number = 0;
display ;
interval;
time = [] as any;
tasks = [] as any;
user = [] as any;
startTime: any = formatDate(new Date(), 'yyyy/MM/dd HH:mm:ss', 'en');
endTime: any= formatDate(new Date(), 'yyyy/MM/dd HH:mm:ss', 'en');
elapsedTime: any = formatDate(new Date(), 'HH:mm:ss', 'en');
constructor(
private authService: AuthService,
private tasksService: TasksService,
private router: Router
) {
setInterval(() => {
this.date = new Date()
}, 1000)
}
ngOnInit(): void {
this.tasksService.getTasks1()
.subscribe(
res => {
this.tasks = res;
console.log(this.tasks);
},
err => console.log(err)
);
}
startTimer() {
console.log("=====>");
this.startTime = new Date();
this.interval = setInterval(() => {
if (this.times === 0) {
console.log(this.startTime);
this.times++;
} else {
this.times++;
}
this.display=this.transform( this.times)
}, 1000);
}
transform(value: number) {
var minutes: number = Math.floor(value / 60);
var hours : number = Math.floor(minutes / 60);
return hours + ':' + minutes;
}
pauseTimer() {
clearInterval(this.interval);
this.endTime = new Date();
//this.userID = new this.userID;
console.log(this.endTime);
const requestBody = {
startTime: this.startTime,
endTime: this.endTime,
elapsedTime: this.endTime - this.startTime
};
this.authService.postTasks({ requestBody })
.subscribe(
res => {
this.time = res;
console.log(this.time);
},
err => console.log(err)
);
}
}
Risposte
Puoi usare Model.prototype.updatein mongoose per aggiornare il sottodocumento timings
.
Tuttavia esistono due scenari:
- Se si desidera eseguire il push delle voci senza la necessità di controllare i duplicati, utilizzare l' $pushoperatore
var filter = {
_id: mongoose.Types.ObjectId('<USER_ID>')
};
var update = {
$push: {
timings: {
startTime: "",
endTime: "",
elapsedTime: ""
}
}
};
db.collection.update(filter, update);
- Se vuoi inviare solo voci distinte, usa l' $addToSetoperatore
var filter = {
_id: mongoose.Types.ObjectId('<USER_ID>')
};
var update = {
$addToSet: {
timings: {
startTime: "",
endTime: "",
elapsedTime: ""
}
}
};
db.collection.update(filter, update);
Nota: mongoose
prima è necessario
const mongoose = require('mongoose');
Correggi il tuo codice come segue, inoltre non puoi ottenere l'ID esatto del sottodocumento, ma puoi ottenere il documento radice aggiornato -
const updatedUser = await User.findOneAndUpdate({
_id: mongoose.Types.ObjectId(req.body._id)
},
{
$addToSet: {
timings: {
startTime,
endTime,
elapsedTime
}
}
}, {
new: true
}).exec();