在MongoDB中插入或更新多个文档
我想在NodeJS和MongoDB支持下实现标签功能,这样我也可以计算出用途.每当用户将标签添加到页面时,我都希望在数据库中推送或更新标签.每个hastag看起来都像这样:
I want to implement hashtags functionality with NodeJS and MongoDB support, so that I can also count the uses. Whenever a user adds hashtags to a page, I want to push or update them in the database. Each hastag looks like this:
{_id:<auto>, name:'hashtag_name', uses: 0}
我面临的问题是用户也可以添加新标签,因此当他单击完成"时,我必须为现有标签增加使用"字段,然后添加新标签.诀窍是如何仅用一条Mongo指令执行此操作?到目前为止,我想到了两种可能的方法来实现这一目标,但是我对这两种方法都不满意:
The problem I'm facing is that the user can add new tags as well, so when he clicks 'done', I have to increment the 'uses' field for the existing tags, and add the new ones. The trick is how to do this with only one Mongo instruction? So far I thought of 2 possible ways of achieving this, but I'm not particularly happy with either:
选项1
我有一项服务,可以在用户开始编写新文章之前从db获取现有标签.基于此,我可以检测到哪些标签是新标签,然后运行2个查询:一个将添加新标签,另一个将更新现有标签
I have a service which fetches the existing tags from the db before the user starts to write a new article. Based on this, I can detect which tags are new, and run 2 queries: one which will add the new tags, and another which will update the existing one
选项2
我将标签列表发送到服务器,然后在其中为每个标签运行find();如果找到一个,我将进行更新,否则,将创建它.
I will send the list of tags to the server, and there I will run a find() for every tag; if I found one, I'll update, if not, I'll create it.
选项3 (暂时没有解决方案)
Option 3 (without solution for now)
最好的选择是运行一个查询,该查询采用标记名数组,对现有标记名执行$ inc操作,然后添加缺失的标记.
Best option would be to run a query which takes an array of tag names, do a $inc operation for the existing ones, and add the missing ones.
问题
有更好的解决方案吗?我可以从选项3获得最终结果吗?
Is there a better solution? Can I achieve the end result from option #3?
您应该执行以下操作,所有这些操作都将在一批中执行,这只是如何执行的摘要代码:
You should do something like this, all of them will be executed in one batch, this is only an snippet idea how to do it:
var db = new Db('DBName', new Server('localhost', 27017));
// Establish connection to db
db.open(function(err, db) {
// Get the collection
var col = db.collection('myCollection');
var batch = col.initializeUnorderedBulkOp();
for (var tag in hashTagList){
// Add all tags to be executed (inserted or updated)
batch.find({_id:tag.id}).upsert().updateOne({$inc: {uses:1}});
}
batch.execute(function(err, result) {
db.close();
});
});