为什么MongoDb游标可以像索引一样被索引?

时间:2014-06-19 18:45:31

标签: javascript arrays mongodb

我注意到如果我使用mongo命令执行JavaScript脚本,脚本可以将游标对象视为数组。

var conn = new Mongo('localhost:27017');
var db = conn.getDB('learn');
db.test.remove({});
db.test.insert({foo: 'bar'});
var cur = db.test.find();
print(cur[0].foo);   //prints: bar
print(cur[1]); // prints: undefined

这似乎超出了JavaScript语言的功能,因为没有办法“重载下标运算符”。那么这实际上是如何运作的?

1 个答案:

答案 0 :(得分:4)

正如文件所说,it is special ability of driver自动cursor[0]转换为cursor.toArray()[0]。您可以通过使用print函数或toArray()覆盖new Error().stack来证明它,以便重新调用callstack。这是:

at DBQuery.a.toArray ((shell):1:32)
at DBQuery.arrayAccess (src/mongo/shell/query.js:290:17)
at (shell):1:2

如您所见,索引调用arrayAccess。怎么样? Here we have a dbQueryIndexAccess function,调用arrayAccess

v8::Handle<v8::Value> arrayAccess = info.This()->GetPrototype()->ToObject()->Get(
                v8::String::New("arrayAccess"));
...
v8::Handle<v8::Function> f = arrayAccess.As<v8::Function>();
...
return f->Call(info.This(), 1, argv);

还有here we have a code,它将索引属性处理程序设置为此函数。 WOW,v8 API让我们能够添加这个处理程序!

DBQueryFT()->InstanceTemplate()->SetIndexedPropertyHandler(dbQueryIndexAccess);

...并将其注入JS游标类,该游标最初是在JS中定义的。

injectV8Function("DBQuery", DBQueryFT(), _global);

Tl; dr :在mongo shell的C ++源代码中被黑客攻击