如何在MongoDB中创建一个通过system.js调用JS函数的索引?

时间:2015-06-27 08:27:30

标签: mongodb

我有两个集合即。白名单(id,count,expiry)和黑名单(id)。 现在我想创建一个索引,当count>> = 200然后调用一个JS函数,它将从白名单中删除文档并将id添加到黑名单。

我可以使用db.collection.createindex({"count":1}, ???);在Mongo中执行此操作 或者我是否需要编写一个守护进程来扫描整个集合?还是有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

您似乎在询问SQL关系数据库中我们称之为"trigger"的内容,这与" index"完全不同。甚至在那个世界里。

在NoSQL世界中,特别是在MongoDB中,那种"服务器逻辑"被降级为"客户"代码操作而不是服务器。将其视为"可扩展性的另一部分"这些产品的philosphy,某些功能,如"触发"由于这些"成本"的立场被带走了分布式数据很多。

所以为了做你想做的事,你可以在"代码"而不是定义数据库"触发"。这个过程很简单,通过.findAndModify()和其他包装变体可用于语言API:

// Increment below 200 and return the modified document
var doc = db.whitelist.findAndModify({
    "query": { "_id": myId, "count": { "$lt": 200 } }
    "update": { "count": { "$inc": 1 } },
    "new": true
});

// Then remove the blacklist where the value meets conditions
if ( doc.hasOwnProperty("count") {
    if ( doc.count >= 200 ) 
        db.blacklist.remove({ "_id": myId });
}

请注意实际的语言API方法变体,因为结构通常不同于"查询/更新" shell方法中提供的键。

基本原则保持不变。修改和获取,然后在满足条件的情况下从其他集合中删除。但它是"两个"前往服务器,没有办法让服务器"触发"当这种情况本身得到满足时。

答案 1 :(得分:0)

  db.whitelist.insert(doc);
  if(db.whitelist.find(criterion).count() >= 200) {
    var bulkRemove = db.whitelist.initializeUnorderedBulkOp();
    var bulkInsert = db.blacklist.initializeUnorderedBulkOp();

    db.whitelist.find(criterion).forEach(
      function(doc){
        bulkInsert.insert({_id:doc._id});
        bulkRemove.find({doc._id}).removeOne();
      }
    );
    bulkInsert.execute();
    bulkRemove.execute();
  }

首先,像往常一样插入文档。由于criterion将使用索引,因此应快速有效地确定if子句。

如果我们有200个或更多符合该标准的文档,我们使用批量操作将ID插入黑名单,并从白名单中删除文档,这些文档将并行执行。

仅将_id写入后备列表的问题是您需要检查列入黑名单的标准是否匹配,因此_id需要包含该标准。

更好的解决方案IMHO将使用名为blacklisted的字段为单个条目标记单个集合的条目,或使用聚合框架查找列入黑名单的文档并使用{{1}将其写入集合管道阶段。遗憾的是,您没有提供示例数据或对您的用例的正确描述,因此您得到了一个未指定的答案。