HTTP-запрос на ввод в узел и mongodb

#javascript #node.js #mongodb #typescript #express

#javascript #node.js #mongodb #машинописный текст #выразить

Вопрос:

Я пытаюсь в MongoDB и node добавить подписки к моему объекту competitionEvent. Моя проблема в том, что я могу написать только одну подписку и не добавлять их одну за другой. Вот мой http-файл:

 const express = require('express')

import * as bodyParser from 'body-parser'
// import { eventApplication } from './compositionRoot'
import { CompetitionModel } from './mongo'

export const app = express()

app.use(bodyParser.json())
// WORKS - find all events
app.get('/events', async (_req: any, res: any) => {
  const comp = await CompetitionModel.find()
  res.send(comp)
})

// WOKRS - find just one event
app.get('/events/:event_id', async (req: any, res: any) => {
  const searchedComp = await CompetitionModel.find(req.params)
  res.send(searchedComp)
})

// WORKS - posts a new comp event
app.post('/new-comp', async (req: any, res: any) => {
  const data = await new CompetitionModel(req.body).save()
  res.json(data)
})

// WORKS - posts a new subscription into a comp
app.put('/update/:event_id', async (req: any, res: any) => {
  const subs = await CompetitionModel.findOneAndUpdate(
    { event_id: req.params.event_id },
    { subscriptions: req.body },
  )
  res.send(subs)
})

// TO TEST - deletes a competition event
app.delete('/delete/:event_id', async (req: any, res: any) => {
  const toDel = await CompetitionModel.deleteOne({
    event_id: req.params.event_id,
  })
  res.json(toDel)
})

  

и вот мой файл mongo:

 const mongoose = require('mongoose')

mongoose.connect('mongodb://localhost:27017/CompetitionEvent')

export const CompetitionSchema = new mongoose.Schema({
  event_id: String,
  compName: String,
  place: String,
  time: String,
  subscriptions: [],
  date: Date,
  cost: {
    currency: String,
    amount: Number,
  },
})

export const CompetitionModel = mongoose.model(
  'CompetitionModel',
  CompetitionSchema,
)

export const connection = () =>
  new Promise((resolve, reject) => {
    mongoose.connection.once('open', () => {
      resolve()
    })
    mongoose.connection.once('error', () => {
      reject('oooooh shit')
    })
  })

  

Каждый раз, когда я пытался его изменить, он либо не изменял competitionEvent, либо ничего не помещал, либо просто заменял старую подписку на новую, что не имеет особого смысла, я уверен, вы согласитесь

Ответ №1:

Вам нужно использовать $push оператор, чтобы добавить новую подписку на ваш конкурс. Предполагая, что req.body поддерживает новую подписку, вы можете сделать:

 app.put('/update/:event_id', async (req: any, res: any) => {
  const subs = await CompetitionModel.findOneAndUpdate(
    { event_id: req.params.event_id },
    { $push: { subscriptions: req.body }},
  )
  res.send(subs)
});
  

Ответ №2:

Прежде всего исправьте свою схему для подписки mongoose.Схема, подобная приведенной ниже, для лучшего приведения типов:

Необязательно

 const CompetitionSchema = new mongoose.Schema({
  event_id: String,
  compName: String,
  place: String,
  time: String,
  subscriptions: [{
   //what ever field you wanna add
   _id: false //if you don't wanna use it as a sub-document
}],
  date: Date,
  cost: {
    currency: String,
    amount: Number,
  },
})
  

Затем в вашем competetionEvent контроллере либо используйте оператор mongo $push для добавления подписки на событие в конце подписки, либо используйте оператор mongo $addToSet для добавления подписки в поле подписки без какого-либо дублирования.

Помните, $push не проверяет, уникальна ли подписка или нет, она просто отправляет элементы, такие как javascript Array.push(). С другой стороны, $addToSet проверяет, существует ли подписка или нет. Если да, то это не добавляет эту подписку. Если нет, то он отправляет его в массив полей.

Я предлагаю использовать $addToSet , поскольку это более безопасно и не создаст никаких дубликатов одной и той же подписки.

код

 app.put('/update/:event_id', async (req: any, res: any) => {
  const subs = await CompetitionModel.findOneAndUpdate(
    { event_id: req.params.event_id },
    { $addToSet: {subscriptions: req.body}},
  )
  res.send(subs)
})