[英]Insert multiple none-existed documents to MongoDB using mongoose
我想保存多個文檔,這些文檔是在井號“#”指示的帖子上找到的標簽。 我在數組中有標簽。 例如:
var tags = ['banana', 'apple', 'orange', 'pie']
我遍歷它們並將其轉換為文檔對象(以將其插入DB)。 問題是我只想在從未插入過新文檔的情況下才將其插入到集合中。 以及是否在我想將插入文檔的userCounter
屬性增加1之前插入。
var tags = ['banana', 'apple', 'pie', 'orange'];
var docs = tags.map(function(tagTitle) {
return {
title: tagTitle,
// useCounter: ??????????
};
});
var Hashtag = require('./models/Hashtag');
/**
* it creates multiple documents even if a document already exists in the collection,
* I want to increment useCounter property of each document if they exist in the collection;
* not creating new ones.
* for example if a document with title ptoperty of 'banana' is inserted before, now increment
* document useCounter value by one. and if apple never inserted to collection, create a new document
* with title of 'apple' and set '1' as its initial useCounter value
*/
Hashtag.create(docs)
.then(function(createdDocs) {
})
.then(null, function(err) {
//handle errors
});
async function findOrIncrease(title) {
let hashtag = await Hashtag.findOne({title});
if(hashtag) {
hashtag.userCounter++;
} else {
hashtag = new Hashtag({title, userCounter: 1});
}
await hashtag.save();
}
可用作:
(async function() {
for(const title of tags)
await findOrIncrease(title);
})()
或者,如果您想並行執行所有操作:
tags.forEach(findOrIncrease);
您可以使用mongodbs索引來加快速度。
感謝@Jonas W的答復,另外我找到了另一個解決方案。 我認為基於標簽數組做出一些承諾並從這些承諾中解析標簽文檔(或出於某些原因拒絕它們)可能會更好(因為它的性能更清晰,更快)。 然后使用Promise.all()
做出完全承諾,提供貓鼬文檔(根據某些條件創建或更新)。 就像這樣:
// some other chains
.then((xxxx) => {
const hashtagsTitles = require('../../src/hashtags/hashtagParser').hashtags(req.newPost.caption);
const Hashtag = require('../../src/database/models/Hashtag');
let findOrIncrease = title =>
new Promise((resolve, reject) => {
Hashtag.findOne({
title
})
.then((hashtag) => {
if (!hashtag) {
new Hashtag({
title,
usageCount: 0
}).save()
.then(hashtag => resolve(hashtag._id))
.catch(err => reject(err));
} else {
hashtag.usageCount++;
hashtag.save()
.then(hashtag => resolve(hashtag._id))
.catch(err => reject(err));
}
})
.catch(err => reject(err));
});
let promiseArr = hashtagsTitles.map((hashtagTitle) =>
findOrIncrease(hashtagTitle)
);
return Promise.all(promiseArr)
.then(results => results)
.catch(err => {
throw err
});
})
.then((hashtags) => {
hashtags.forEach((hashtag) => req.newPost.hashtags.push(hashtag));
})
//there might be some other chains
這里還有一個很好的指南: 貓鼬-如果不存在,則創建文檔,否則,無論哪種情況,都要更新-返回文檔
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.