我正在创建一个多用户字典,几个用户可以在其中添加单词。我不希望同一词有重复的意思。添加单词时,我能够防止出现重复现象,但是在更新单词时却无法防止出现重复现象。例如,数据库中有一个单词“ apple”,让我们假设有人想要更新一个单词“ apply”并无意中写了“ apple”,在这种情况下,更新的单词“ apple”不应该进入数据库,因为那里已经有这样的词了。请帮我。
Words API
const express = require('express');
const router = express.Router();
const Word = require('../../models/Word');
const validateWordInput = require('../../validation/word');
const passport = require('passport');
// @route GET api/words/test
// @desc tests words route
// @access Public
router.get('/test', (req, res) => res.json({ msg: 'Words works' }));
// @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));
}
});
}
);
// @route Put api/words/:id
// @desc Update a word by id
// @access Private
router.put(
'/:id',
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);
}
Profile.findOne({ user: req.user.id }).then(profile => {
Word.findById(req.params.id)
.then(word => {
// Check for word owner
if (word.user.toString() !== req.user.id) {
return res
.status(401)
.json({ notauthorized: 'User not authorized' });
}
const wordID = req.params.id;
const wordInput = req.body;
// Update
Word.findByIdAndUpdate(
{ _id: wordID },
{ $set: wordInput },
{ returnOriginal: false },
(err, word) => {
if (err) {
console.log(err);
}
}
).then(word => {
res.json(word);
});
})
.catch(err => res.status(404).json({ nowordfound: 'No word found' }));
});
}
);
// @route GET api/words
// @desc Dislay all words
// @access Public
router.get('/', (req, res) => {
Word.find()
.sort({ date: -1 })
.then(words => res.json(words))
.catch(err => res.status(404).json({ nonwordsfound: 'No words found' }));
});
//@route Get api/words/:id
//@desc Get word by id
//@access Public
router.get('/:id', (req, res) => {
Word.findById(req.params.id)
.then(word => res.json(word))
.catch(err =>
res.status(404).json({ nonwordfound: 'No word found with that ID' })
);
});
//@route DELETE api/words/:id
//@desc DELETE word
//@access Private
router.delete(
'/:id',
passport.authenticate('jwt', { session: false }),
(req, res) => {
Profile.findOne({ user: req.user.id }).then(profile => {
Word.findById(req.params.id)
.then(word => {
// Check for post owner
if (word.user.toString() !== req.user.id) {
return res
.status(401)
.json({ notauthorized: 'User not authorized' });
}
// Delete
word.remove().then(() => res.json({ success: true }));
})
.catch(err => res.status(404).json({ postnotfound: 'No post found' }));
});
}
);
module.exports = router;
我使用以下代码来防止加法时出现重复。
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
});
我应该写什么代码来在更新时执行相同的操作?
答案 0 :(得分:2)
在执行Word.findByIdAndUpdate()
之前,您可以检查req.body
中的文本是否与数据库中现有的单词匹配。
// @route Put api/words/:id
// @desc Update a word by id
// @access Private
router.put(
'/:id',
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);
}
Profile.findOne({ user: req.user.id }).then(profile => {
Word.findById(req.params.id)
.then(word => {
// Check for word owner
if (word.user.toString() !== req.user.id) {
return res
.status(401)
.json({ notauthorized: 'User not authorized' });
}
const wordID = req.params.id;
const wordInput = req.body;
//find all words
Word.find()
.then((allWords) => {
//create an array of strings using each word ("apple", "apricot", ...etc)
const wordStrings = allWords.map((word) => word.ugrWordCyr) //not sure if thats the property that has the word-spelling
//check if user input already exists in all words
if(wordStrings.includes(req.body.ugrWordCyr)){
return res.status(400).json({ error : "word already exists" })
}
// Update
Word.findByIdAndUpdate(
{ _id: wordID },
{ $set: wordInput },
{ returnOriginal: false },
(err, word) => {
if (err) {
console.log(err);
}
}).then(word => {
res.json(word);
});
})
.catch((errors) => {
return res.status(400).json({ errors: "could not find any words" })
})
})
.catch(err => res.status(404).json({ nowordfound: 'No word found' }));
});
}
);
或者,您也可以在设置猫鼬模式时更新Word
模型并使用unique
属性。我想您的架构看起来像这样:
const mongoose = require("mongoose")
const wordSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
ugrWordCyr: { type: String, unique: true}, <-- set unique to true
rusTranslation: { type: String },
example: { type: String },
exampleTranslation: { type: String },
origin: { type: String },
sphere: { type: String },
lexis: { type: String },
grammar: { type: String },
partOfSpeech: { type: String },
style: { type: String }
})
const Word = mongoose.model("Word", userSchema)
module.exports = Word
现在,当您使用findByIdAndUpdate()
时,除非您将新的/唯一的字符串传递给ugrWordCyr
或用作显式单词的任何东西,否则它将不会完成。
Word.findByIdAndUpdate(
{ _id: wordID },
{ $set: wordInput },
{ returnOriginal: false },
(err, word) => {
if (err) {
console.log(err);
}
}
).then(word => {
res.json(word);
});
.catch(err => {
return res.status(400).json({ error: "could not update word" })
})
})