使用猫鼬将多个不存在的文档插入到MongoDB



我想保存多个文档,这些文档是在由哈希符号"#"指示的帖子中找到的标签。我在数组中有标签。例如:

var tags = ['banana', 'apple', 'orange', 'pie']

我循环访问它们并将 转换为文档对象(将它们插入数据库(。 问题是我只想将文档插入到集合中,前提是它以前从未插入过。 如果它在我想将插入的文档的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索引来加快速度。

感谢 W @Jonas回复,我还有另一种解决方案。我认为根据标签数组做出一些承诺并从这些承诺中解析标签文档(或出于某些原因拒绝它们(可能会更好(因为它的性能更清晰、更快(。然后使用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

这里还有一个很好的指南:猫鼬 - 如果不存在,则创建文档,否则,更新 - 在这两种情况下返回文档

最新更新