#node.js #mongodb #express
#node.js #mongodb #выразить
Вопрос:
Я пытался отправить данные из MongoDB пользователю, который вошел в систему. Поэтому всякий раз, когда пользователь запускает запрос на публикацию данных, он должен быть отправлен и вложен под этого пользователя.
метод 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});
});
Используя этот метод, я могу успешно сохранять данные в MongoDB, но я не понимаю, как вложить их под конкретного пользователя.
Это должно быть так:
const userSchema = new Schema({
firstname: String,
lastname: String,
email: String,
password: String,
timings: [{
startTime: String,
endTime: String,
elapsedTime: String
}]
});
Я пробовал разные способы, но все они выдавали мне ошибки. Единственный способ, который дает мне наибольшую уверенность, на самом деле заключается в указании пути ‘/posttasks /:_id’ и присвоении add.function()
но поскольку я новичок в Mongo, Express и Node.js Я не смог этого сделать
Угловой код
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)
);
}
}
Комментарии:
1. вы хотите добавить или обновить тайминги?
2. @Kunal Mukherjee Мне нужно добавить массив результатов, каждый раз, когда пользователь нажимает кнопку, он добавляет еще один индекс массива (в данном случае «тайминги»), поэтому, когда пользователь открывает страницу, все тайминги под этим пользователем будут опубликованы
3. Итак, каждый раз, когда вызывается
/savetasks
API, он вставляет новый документ, верно?4. @Kunal Mukherjee точно, он будет вставлен под пользователем, который вошел в систему в этот момент. Таким образом, результатом будет массив документов, и, по-видимому, у каждого документа будут разные тайминги
Ответ №1:
Вы можете использовать Model.prototype.update
в mongoose для обновления вложенного документа timings
.
Однако существует два сценария —
- Если вы хотите отправлять записи без необходимости проверять дубликаты, используйте
$push
operator
var filter = {
_id: mongoose.Types.ObjectId('<USER_ID>')
};
var update = {
$push: {
timings: {
startTime: "",
endTime: "",
elapsedTime: ""
}
}
};
db.collection.update(filter, update);
- Если вы хотите отправлять только отдельные записи, используйте
$addToSet
operator
var filter = {
_id: mongoose.Types.ObjectId('<USER_ID>')
};
var update = {
$addToSet: {
timings: {
startTime: "",
endTime: "",
elapsedTime: ""
}
}
};
db.collection.update(filter, update);
Примечание: Сначала требуется mongoose
const mongoose = require('mongoose');
Исправьте свой код на приведенный ниже, также вы не можете получить точный идентификатор вложенного документа, но вы можете получить обновленный корневой документ —
const updatedUser = await User.findOneAndUpdate({
_id: mongoose.Types.ObjectId(req.body._id)
},
{
$addToSet: {
timings: {
startTime,
endTime,
elapsedTime
}
}
}, {
new: true
}).exec();
Комментарии:
1. это абсолютно понятно, как использовать операторы $ push или $ addToSet. У меня проблема, как получить идентификатор пользователя, чтобы я мог хранить данные под этим пользователем
2. @MarkoMalbasic вам просто нужно передать
userId
пользователя, которого вы хотите обновить, в фильтр, смотрите обновленный ответ3. «ReferenceError: mongoose не определен» Сейчас я получаю эту ошибку… Я немного поиграю! В любом случае спасибо
4. И теперь мой вопрос в том, ‘<USER_ID>’ относится к чему? Как я могу это определить?
5. @MarkoMalbasic
UserId
— это_id
имя текущего пользователя, которое вы можете получить из вашего экспресс-контроллера, такого какreq.body.userId
или angular app