Nodejs/MongoDB:将动态创建的对象推入数组中

huangapple go评论81阅读模式
英文:

Nodejs/MongoDB: Push dynamically created object into array

问题

以下是您要翻译的内容:

我想使用mongodb和nodejs将对象推入数组
我的单词模式如下

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

const wordSchema = new Schema({
  user: {
    type: Schema.Types.ObjectId,
    ref: "users"
  },
  date: {
    type: Date,
    default: Date.now
  },
  ugrWordCyr: {
    type: String,
    required: true
  },
  ugrWordArb: {
    type: String
  },
  rusTranslation: {
    type: String,
    required: true
  },
  examples: [
    {
      exCyr: { type: String },
      trRus: { type: String },
      exLat: { type: String },
      trEng: { type: String },
      exArab: { type: String }
    }
  ],
  origin: {
    type: String
  },
  sphere: {
    type: String
  },
  see: {
    type: Boolean,
    default: false
  },
  lexis: {
    type: String
  },
  grammar: {
    type: String
  },
  partOfSpeech: {
    type: String
  },
  style: {
    type: String
  }
});

module.exports = Word = mongoose.model("words", wordSchema);
如您所见模式中有一个示例数组需要用动态创建的对象填充它因此在我的单词API中我正在做这件事但它不起作用

// @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,
          ugrWordArb: req.body.ugrWordArb,
          rusTranslation: req.body.rusTranslation,
          origin: req.body.origin,
          sphere: req.body.sphere,
          lexis: req.body.lexis,
          grammar: req.body.grammar,
          partOfSpeech: req.body.partOfSpeech,
          style: req.body.style
        });
        // Social
        newWord.examples = [];
        /* if (req.body.exCyr) newWord.examples.exCyr = req.body.exCyr;
        if (req.body.trRus) newWord.examples.trRus = req.body.trRus;
        if (req.body.exLat) newWord.examples.exLat = req.body.exLat;
        if (req.body.trEng) newWord.examples.trEng = req.body.trEng;
        if (req.body.exArab) newWord.examples.exArab = req.body.exArab; */
        newWord.examples.push({
          exArab:req.body.exArab,
          trRus:req.body.trRus,
          exLat:req.body.exLat,
          trEng:req.body.trEng,
          exArab:req.body.exArab
        })
        newWord.save().then(word => {
          //now update user model
          User.findOne({ _id: req.user.id })
            .then(foundUser => {
              foundUser.score = foundUser.score + 150;
              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' });
            });
        });
      }
    });
  }
);

我做错了什么前端没问题
英文:

I want to push objects into array using mongodb and nodejs.
My word schema is:

const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const wordSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: "users"
},
date: {
type: Date,
default: Date.now
},
ugrWordCyr: {
type: String,
required: true
},
ugrWordArb: {
type: String
},
rusTranslation: {
type: String,
required: true
},
examples: [
{
exCyr: { type: String },
trRus: { type: String },
exLat: { type: String },
trEng: { type: String },
exArab: { type: String }
}
],
origin: {
type: String
},
sphere: {
type: String
},
see: {
type: Boolean,
default: false
},
lexis: {
type: String
},
grammar: {
type: String
},
partOfSpeech: {
type: String
},
style: {
type: String
}
});
module.exports = Word = mongoose.model("words", wordSchema);

As you can see there is the example array in the schema. It is needed to be fulled with dynamically created objects. So in my words api I am doing this thing, but it does not work.

// @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,
ugrWordArb: req.body.ugrWordArb,
rusTranslation: req.body.rusTranslation,
origin: req.body.origin,
sphere: req.body.sphere,
lexis: req.body.lexis,
grammar: req.body.grammar,
partOfSpeech: req.body.partOfSpeech,
style: req.body.style
});
// Social
newWord.examples = [];
/* if (req.body.exCyr) newWord.examples.exCyr = req.body.exCyr;
if (req.body.trRus) newWord.examples.trRus = req.body.trRus;
if (req.body.exLat) newWord.examples.exLat = req.body.exLat;
if (req.body.trEng) newWord.examples.trEng = req.body.trEng;
if (req.body.exArab) newWord.examples.exArab = req.body.exArab; */
newWord.examples.push({
exArab:req.body.exArab,
trRus:req.body.trRus,
exLat:req.body.exLat,
trEng:req.body.trEng,
exArab:req.body.exArab
})
newWord.save().then(word => {
//now update user model
User.findOne({ _id: req.user.id })
.then(foundUser => {
foundUser.score = foundUser.score + 150;
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' });
});
});
}
});
}
);

What am I doing wrong? In front end it is all right!

答案1

得分: 0

I think it is because you are trying to push onto an array that doesn't exist yet on the Model instance.

Either add the empty array to the Model instance when you create it or save the model twice. After creating the empty array and then after pushing onto it.

Try this:

const newWord = new Word({
          user: req.user.id,
          ugrWordCyr: req.body.ugrWordCyr,
          ugrWordArb: req.body.ugrWordArb,
          rusTranslation: req.body.rusTranslation,
          origin: req.body.origin,
          sphere: req.body.sphere,
          lexis: req.body.lexis,
          grammar: req.body.grammar,
          partOfSpeech: req.body.partOfSpeech,
          style: req.body.style,
          examples: []; //add it here
        });

or this:

newWord.examples = [];
        
newWord.save().then(word => {
    // now push into the added array and then save again
    newWord.examples.push({
        exArab:req.body.exArab,
        trRus:req.body.trRus,
        exLat:req.body.exLat,
        trEng:req.body.trEng,
        exArab:req.body.exArab
    })
});
英文:

I think it is because you are trying to push onto an array that doesn't exist yet on the Model instance.

Either add the empty array to the Model instance when you create it or save the model twice. After creating the empty array and then after pushing onto it.

Try this:

const newWord = new Word({
user: req.user.id,
ugrWordCyr: req.body.ugrWordCyr,
ugrWordArb: req.body.ugrWordArb,
rusTranslation: req.body.rusTranslation,
origin: req.body.origin,
sphere: req.body.sphere,
lexis: req.body.lexis,
grammar: req.body.grammar,
partOfSpeech: req.body.partOfSpeech,
style: req.body.style,
examples: []; //add it here
});

or this:

        newWord.examples = [];
newWord.save().then(word => {
// now push into the added array and then save again
newWord.examples.push({
exArab:req.body.exArab,
trRus:req.body.trRus,
exLat:req.body.exLat,
trEng:req.body.trEng,
exArab:req.body.exArab
})

答案2

得分: 0

这是一个正确的解决方案。不需要将任何内容推送到数组中。

const newWord = new Word({
  user: req.user.id,
  ugrWordCyr: req.body.ugrWordCyr,
  ugrWordArb: req.body.ugrWordArb,
  rusTranslation: req.body.rusTranslation,
  origin: req.body.origin,
  sphere: req.body.sphere,
  lexis: req.body.lexis,
  grammar: req.body.grammar,
  partOfSpeech: req.body.partOfSpeech,
  style: req.body.style,
  examples: req.body.examples
});
英文:

This is a correct solution. No need to push anything into array.

const newWord = new Word({
user: req.user.id,
ugrWordCyr: req.body.ugrWordCyr,
ugrWordArb: req.body.ugrWordArb,
rusTranslation: req.body.rusTranslation,
origin: req.body.origin,
sphere: req.body.sphere,
lexis: req.body.lexis,
grammar: req.body.grammar,
partOfSpeech: req.body.partOfSpeech,
style: req.body.style,
examples: req.body.examples
});

huangapple
  • 本文由 发表于 2020年1月6日 21:22:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/59612907.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定