Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/413.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从PHP插入时在MongoDB上执行JS_Php_Javascript_Json_Mongodb - Fatal编程技术网

从PHP插入时在MongoDB上执行JS

从PHP插入时在MongoDB上执行JS,php,javascript,json,mongodb,Php,Javascript,Json,Mongodb,当使用mongo shell时,我可以运行如下操作: 我无法使用php实现同样的效果。 我希望做的是运行类似于 找到 { "_id" : ...., "col" : 123 } 收藏中。我怎样才能做到这一点?有可能吗? 如果你想要更多的细节,我试着模仿autoincrement。我正在编写的这个函数应该检索incremental字段最后使用的值,对其进行递增并返回值,从而为插入的文档分配一个唯一的值。JavaScript函数在BSON中是一种一流的类型(请参阅),因此在这

当使用mongo shell时,我可以运行如下操作:

我无法使用php实现同样的效果。 我希望做的是运行类似于

找到

{
   "_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})