NODE.jsとExpressを使用してMongoDBデータをネストされた配列に投稿する方法

Aug 23 2020

私は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
}]
});

私はさまざまな方法を試しましたが、それらすべてが私にエラーを与えていました。私に最も信頼を与える1つの方法は、実際にはパス '/ 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)
    );
}
}

回答

KunalMukherjee Aug 23 2020 at 14:24

Model.prototype.updatein mongooseを使用して、サブドキュメントを更新できますtimings

ただし、2つのシナリオがあります-

  1. 重複をチェックする必要なしにエントリをプッシュしたい場合は、$push演算子を使用してください
    var filter = {
        _id: mongoose.Types.ObjectId('<USER_ID>')
    };
    
    var update = {
        $push: {
            timings: {
                startTime: "",
                endTime: "",
                elapsedTime: ""
            }
        }
    };
    
    db.collection.update(filter, update);
  1. 個別のエントリのみをプッシュする場合は、$addToSet演算子を使用します
    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');

コードを以下に修正します。また、正確なサブドキュメントのIDを取得することはできませんが、更新されたルートドキュメントを取得することはできます-

const updatedUser = await User.findOneAndUpdate({
        _id: mongoose.Types.ObjectId(req.body._id)
    },
    {
        $addToSet: {
            timings: {
                startTime, 
                endTime, 
                elapsedTime
            }
        }
    }, {
        new: true
    }).exec();