有没有办法覆盖Mongodb中的默认函数?

时间:2014-12-11 15:01:59

标签: mongodb mongo-shell

所以我想做的是让findOne更像在Meteor中工作,但是通过Mongo shell。简而言之,我希望能够执行类似db.collection.findOne("thisIsAnId")之类的操作,并让它在该集合中查找该ID。

我尝试加载一个包含此文件的文件......

db.collection.findOne = function(query, fields, options){
    if(typeof query === "string") {
        return db.collection.originalFindOne({_id : query}, fields, options);
    }

    return db.collection.originalFindOne(query, fields, options); 
}

originalFindOne只会链接到默认findOne,这根本不起作用。所以在没有运气找到覆盖默认函数的方法之后,我想也许我可以创建一个像db.collection.simpleFindOne()之类的新函数,但是我找不到将它附加到mongo shell的方法,以便它将适用于任何系列。

任何人都对mongo内部的工作方式有所了解,可以给我一些帮助吗?

1 个答案:

答案 0 :(得分:5)

尝试将此代码段添加到您的某个Mongo配置文件中:

(function() {

// Duck-punch Mongo's `findOne` to work like Meteor's `findOne`
if (
  typeof DBCollection !== "undefined" && DBCollection &&
  DBCollection.prototype && typeof DBCollection.prototype.findOne === "function" &&
  typeof ObjectId !== "undefined" && ObjectId
) {
  var _findOne = DBCollection.prototype.findOne,
      _slice = Array.prototype.slice;
  DBCollection.prototype.findOne = function() {
    var args = _slice.call(arguments);
    if (args.length > 0 && (typeof args[0] === "string" || args[0] instanceof ObjectId)) {
      args[0] = { _id: args[0] };
    }
    return _findOne.apply(this, args);
  };
}

})();

我最初通过在Mongo shell中键入DBCollection找到db.myCollection.constructor对象/类。然后我通过验证(a)findOne是否可全局访问,(b)DBCollection存在,以及(c)DBCollection.prototype确认typeof DBCollection.prototype.findOne === "function"已在其原型上定义(很像代码片段。)


编辑:添加了逻辑分支,以涵盖基于ObjectId的ID。