Обновление поля в MondoDB

Я пишу многопользовательский онлайн-словарь. Я хочу внедрить доску лидеров, т.е. Атрибут "score" увеличивается, как только пользователь добавляет слово. У меня есть приблизительное представление о том, как это сделать, и я попробовал одно решение, однако оно не работает. Не могли бы вы направить меня?

Маршрут API Word

const express = require('express');
const router = express.Router();
const Word = require('../../models/Word');
const User = require('../../models/User');

const validateWordInput = require('../../validation/word');
const passport = require('passport');

// @route  POST api/words
// @desc   Add words to profile
// @access Private
router.post(
  '/',
  passport.authenticate('jwt', { session: false }),
  (req, res) => {
    const { errors, isValid } = validateWordInput(req.body);

    // Check validation
    if (!isValid) {
      // Return any errors
      return res.status(400).json(errors);
    }

    Word.find({}).then(word => {
      if (
        word.filter(
          wrd =>
            wrd.ugrWordCyr.toString().toLowerCase() ===
            req.body.ugrWordCyr.toLowerCase()
        ).length !== 0
      ) {
        return res
          .status(404)
          .json({ wordalreadyexists: 'Word already exists' });
      } else {
        const newWord = new Word({
          user: req.user.id,
          ugrWordCyr: req.body.ugrWordCyr,
          rusTranslation: req.body.rusTranslation,
          example: req.body.example,
          exampleTranslation: req.body.exampleTranslation,
          origin: req.body.origin,
          sphere: req.body.sphere,
          lexis: req.body.lexis,
          grammar: req.body.grammar,
          partOfSpeech: req.body.partOfSpeech,
          style: req.body.style
        });

        newWord.save().then(word => res.json(word));
        User.update(
          { _id: '5cf0cb78b3105d1ba8e30331' },
          { $inc: { score: 1 } }
        );
      }
    });
  }
);

Пользовательская модель

Здесь находится атрибут score

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// Create schema
const userSchema = new Schema({
  name: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true
  },
  password: {
    type: String,
    required: true
  },
  score: {
    type: Number,
    default: 0
  },
  avatar: {
    type: String
  },
  date: {
    type: Date,
    default: Date.now
  }
});

module.exports = User = mongoose.model('users', userSchema);

что в первую очередь вы хотели бы сделать с помощью этой функции?

Chris Ngo 31.05.2019 11:09

Я хочу, чтобы мое поле оценки обновлялось, когда новое слово добавляется через форму.

NZMAI 31.05.2019 11:11
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
47
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

После успешного сохранения слова мы должны обновить количество пользователей.

Чтобы обновить оценку соответствующего пользователя, вы можете сделать следующее:

newWord.save().then((word) => {

    //now update user model
    User.findOne({ _id: req.user.id }) <-- or an id you would like
        .then((foundUser) => {
             foundUser.score = foundUser.score + 1

             foundUser.save()
                .then((savedUser) => {
                    res.json({ word, savedUser })
                })
                .catch((err) => {
                    return res.status(400).json({ error: "could not add score"})
                })
        })
        .catch((err) => {
           return res.status(400).json({ error: "could not find user"})
        })

})

Вы получите сообщение об ошибке об отправке нескольких ответов, поскольку вы пытаетесь отправить один после слова «сохранить» и после обновления пользователя. Также мне было интересно, является ли хорошей практикой отправлять ответ клиенту до успешного завершения операций с базой данных?

Asaf Aviv 31.05.2019 11:24

@AsafAviv, это интересно, интересно, не лучше ли просто отправить один ответ в виде массива, включающего все ответы. OP, вероятно, придется обновить свои обработчики обещаний на интерфейсе, чтобы использовать их.

Chris Ngo 31.05.2019 11:28

Однако получить второй ответ невозможно, потому что res.json звонит res.end

Asaf Aviv 31.05.2019 11:32

@AsafAviv, верно, так что, возможно, мы могли бы удалить первый res.json(), а затем передать слово response в объекте с сохраненным пользователем

Chris Ngo 31.05.2019 11:35

Нет необходимости в массиве, мы можем отправить его как json после того, как мы обновим счет как res.json({ word, savedUser });

Asaf Aviv 31.05.2019 11:36

@AsafAviv спасибо, я не понял этого, прочитав это снова, ха-ха. :)

Chris Ngo 31.05.2019 11:36

@ChristopherNgo, я попробовал ваш код, но, к сожалению, он не работает.

NZMAI 31.05.2019 12:05

@NZMAI значение, вероятно, не отображается так, как вы хотите, во внешнем интерфейсе, вы получаете какие-либо ошибки при переходе по этому маршруту?

Chris Ngo 31.05.2019 12:11

@ChristopherNgo, могу я спросить вас, где хранится значение «score»? В вашей реализации?

NZMAI 31.05.2019 12:14

@NZMAI значение оценки должно исходить из модели пользователя. Поскольку мы можем найти пользователя с помощью User.findOne(), мы можем использовать возвращенные данные, которые мы называем foundUser. foundUser будет иметь свойство, называемое score. И мы просто обновляем счет, как задумано. Проблема, с которой вы можете столкнуться, заключается в том, что вы могли добавить оценку в качестве нового свойства внутри своей модели, но у существующих пользователей этого свойства еще нет. Поэтому, когда вы пытаетесь обновить его, нет смысла обновлять.

Chris Ngo 31.05.2019 12:17

Хорошо, но когда я добавляю слово, оценка не обновляется. Я посмотрел в console.info. при добавлении слова консоль регистрирует POST локальный: 3000/API/слов 400 (неверный запрос).

NZMAI 31.05.2019 12:22

Давайте продолжить обсуждение в чате.

Chris Ngo 31.05.2019 12:24

Другие вопросы по теме