#javascript #node.js #database #mongodb #mongoose
#javascript #node.js #База данных #mongodb #мангуст
Вопрос:
Я новичок в Nodejs и пытаюсь создать видео с хэштегом. В базе данных уже хранятся хэштеги и хэштег, который создаст пользователь (который будет добавлен при отправке видео).
Например, я добавляю более 2 хэштегов, приведенный ниже код работает для 2 случаев:
- Если в базе данных нет хэштега, он успешно создал и добавил все хэштеги к видео
- Если hashtags уже есть в БД, он успешно добавил видео
- Но когда в БД уже есть несколько хэштегов, а другого нет. К видео добавляется только несколько хэштегов, а не все добавленные хэштеги. Я не знаю почему. Я хочу исправить этот случай.
У меня есть 2 схемы, подобные этой:
// Video schema
const videoSchema = new mongoose.Schema({
url: {
type: String
},
hashtag: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'Hashtag'
}
})
и
// Hashtag schema
const hashtagSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true,
}
})
Пользователь разместит подобное сообщение на сервере. В этом примере Tag-In-DB-Уже находится в DB, а новый тег вводится пользователем
{
"url": "https://youtube.com/JvDAQD4",
"hashtag": ["Tag-In-DB-Already", "New-Tag"]
}
videoObj, подобный этому
const videoObj = new Video({
url: data.URL,
hashtag: []
})
Для проверки кода, подобного этому, мне нужно нажать ObjectId (из hashtag) в hashtagArr выше. Я проверяю каждый хэштег, если хэштега нет в БД, он будет добавлен в БД, а затем отправлен в массив. Если хэштег находится в БД, он также добавляется в массив. Я хочу, чтобы все хэштеги, отправленные пользователем, были добавлены.
export const addHashtagToVideo = async (hashtagArr, videoObj) => {
await hashtagArr.forEach(hashtagName => { // for each hashtag check
Hashtag.findOne({ name: hashtagName.toLowerCase() }, (err, resp) => {
if (err) return
if (!resp) { // if there is no hashtag in DB
addNewHashtagToDB(hashtagName) // run add new hashtag function
.then(hashtagId => { // newHashtag._id returned from below function
videoObj.hashtag.push({ _id: hashtagId })
})
} else {
videoObj.hashtag.push({ _id: resp._id }) // if found in DB, also pushed to video
}
})
})
}
export const addNewHashtagToDB = async (hashtagName) => {
const newHashtag = await new Hashtag({
name: hashtagName.toLowerCase(),
})
newHashtag.save()
return newHashtag._id
}
Спасибо за помощь
Ответ №1:
вам нужно знать, что такое возврат функции…
export const addHashtagToVideo = async (hashtagArr, videoObj) => {
const waitAllDone = hashtagArr.map(async tag => { // tag in hashtagArr
const doc = await addNewHashtagToDB(tag) // find it or create it
return doc.id
})
const ary = await Promise.all(waitAllDone) // [id1, id2]
videoObj.hashtag = ary
// return videoObj
}
export const addNewHashtagToDB = async tag => {
const name = tag.toLowerCase() // whatever tag is, fix it
let doc = await Hashtag.findOne({ name }).exec() // try to find it
if (!doc) {
// not exist
doc = new Hashtag({ name }) // create new doc
await doc.save()
}
return doc
}
другая версия
export const addHashtagToVideo = async (hashtagArr, videoObj) => {
const waitAllDone = hashtagArr.map(addNewHashtagToDB) // amazing
const ary = await Promise.all(waitAllDone) // [id1, id2]
videoObj.hashtag = ary // replace it to prevent duplicat
// return videoObj
}
export const addNewHashtagToDB = async tag => {
const name = tag.toLowerCase() // whatever tag is, fix it
let doc = await Hashtag.findOne({ name }).exec() // try to find it
if (!doc) {
// not exist
doc = new Hashtag({ name }) // create new doc
await doc.save()
}
return doc.id // return it here
}