从PHP插入时在MongoDB上执行JS
当使用mongo shell时,我可以运行如下操作: 我无法使用php实现同样的效果。 我希望做的是运行类似于 找到从PHP插入时在MongoDB上执行JS,php,javascript,json,mongodb,Php,Javascript,Json,Mongodb,当使用mongo shell时,我可以运行如下操作: 我无法使用php实现同样的效果。 我希望做的是运行类似于 找到 { "_id" : ...., "col" : 123 } 收藏中。我怎样才能做到这一点?有可能吗? 如果你想要更多的细节,我试着模仿autoincrement。我正在编写的这个函数应该检索incremental字段最后使用的值,对其进行递增并返回值,从而为插入的文档分配一个唯一的值。JavaScript函数在BSON中是一种一流的类型(请参阅),因此在这
{
"_id" : ....,
"col" : 123
}
收藏中。我怎样才能做到这一点?有可能吗?
如果你想要更多的细节,我试着模仿autoincrement。我正在编写的这个函数应该检索incremental字段最后使用的值,对其进行递增并返回值,从而为插入的文档分配一个唯一的值。JavaScript函数在BSON中是一种一流的类型(请参阅),因此在这两个示例中(JS shell和PHP)您将在字段中存储函数本身。如果要评估函数,必须执行服务器端JavaScript。考虑这个例子:
<?php
$m = new Mongo();
$db = $m->test;
$c = $db->foo;
$c->drop();
$f = 'function() { return 123; }';
$c->insert(['f' => new MongoCode($f)]);
var_dump($c->findOne()['f']);
$g = <<<'END'
function() {
var doc = db.foo.findOne();
db.foo.update(
{ _id: doc._id },
{ $set: { f: doc.f() }}
);
}
END;
$db->execute(new MongoCode($g));
$c->insert(['f' => new MongoCode($f)]);
var_dump($c->findOne()['f']);
如果您的函数依赖于某些外部状态(例如,它需要运行查询来计算其结果),您可能希望将其存储在单独的字段中,并定期迭代文档并更新另一个字段以保存其输出。在实现这一点时,请记住这有几个并发限制。您不能完全按照您的意愿使用MongoDB。在shell中运行示例时,它首先调用
db.eval…
位,然后将计算结果作为文档的一部分传递。Mongo在写入操作期间唯一要计算的是作为更新(或upsert,如果需要)一部分的特殊修改器字段。不过,这些都不允许您对每个收集计数器进行计数
对于autoincrement,您需要执行两个查询。您可以使用find和modify
以原子方式递增和检索一个数字,然后将其分配给您的行
值
下面是如何从外壳中执行此操作:
counter = db.counters.findAndModify({
query: {_id: "line-counter"},
update: {$inc: {value: 1}},
new: true,
upsert: true}).value
db.sandbox.insert({line: counter})
既然你想做一个激励场,请让我说你做错了 正如@jmikola所说,服务器端规避存在严重问题,包括它几乎与包括分片在内的所有内容都不兼容。事实上,我建议不要太多地学习服务器端执行,甚至我不会向您展示如何执行的示例 我建议您远离JS的服务器端执行,它不像SQL中的存储过程或触发器,实际上也不运行相同的操作。JS控制台只是另一个驱动程序,非常类似于MySQL控制台,我认为这就是您感到困惑的地方,您可能认为控制台类似于服务器端执行(存储过程等),但事实并非如此,它只是另一个客户机 Map Reduce是唯一真正受支持的“服务器端”执行。当然,您可以将脚本存储在system.js中以备将来使用,但这更适合于将繁琐的MR脚本存储在DB中,这样您就不必不断地将它们写出来或通过网络反复发送大型文件 我正在编写的这个函数应该检索增量字段最后使用的值 这个函数肯定不会像您预期的那样工作,因为并发会使新ID无效,因为它可能已经被另一个插入使用过。当然,这取决于插入的频率,但即使在轻微的负载下,您的ID也不会正确增加 要实现自动递增ID,您可以实际使用findandmodify,如图所示:@MrKurts answer内。我想“Echo$fnc”可以解决您的问题。
<?php
$m = new Mongo();
$db = $m->test;
$c = $db->foo;
$c->drop();
$f = 'function() { return 123; }';
$c->insert(['f' => new MongoCode($f)]);
var_dump($c->findOne()['f']);
$g = <<<'END'
function() {
var doc = db.foo.findOne();
db.foo.update(
{ _id: doc._id },
{ $set: { f: doc.f() }}
);
}
END;
$db->execute(new MongoCode($g));
$c->insert(['f' => new MongoCode($f)]);
var_dump($c->findOne()['f']);
object(MongoCode)#7 (2) {
["code"]=>
string(26) "function() { return 123; }"
["scope"]=>
array(0) {
}
}
float(123)
counter = db.counters.findAndModify({
query: {_id: "line-counter"},
update: {$inc: {value: 1}},
new: true,
upsert: true}).value
db.sandbox.insert({line: counter})