插入槽中使用的存储函数 PHP 运行多次 [英] Stored function used in insert trough PHP runs multiple times

查看:31
本文介绍了插入槽中使用的存储函数 PHP 运行多次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图理解在 mongodb 2.4.3 win32 中使用 PHP 的奇怪行为.我尝试让服务器端生成序列 ID.

I'm trying to understand a strange behavior using PHP with mongodb 2.4.3 win32. I try to have server side generated sequence ids.

当使用存储函数作为参数之一插入文档时,似乎每次插入都会多次调用存储函数.

When inserting documents using a stored function as one of the parameters it seems that the stored function is called several times at each insertion.

假设我有一个这样初始化的计数器:

Let's say I have a counter initialized like this:

db.counters.insert( { _id: "uqid", seq: NumberLong(0) } );

我有一个名为 getUqid 的存储函数,它被定义为

I have a stored function named getUqid which is defined as

db.system.js.save( 
    { _id: "getUqid", 
      value: function () { 
                  var ret = db.counters.findAndModify(
                  { query: { _id: "uqid" }, 
                    update: { $inc: { seq: NumberLong(1) } }, 
                    new: true 
                  } );
                  return ret.seq; 
                  } 
             }  );

当我像这样进行三个插入时:

When I do three insertions like this:

$conn->test->ads->insert(['qid' => new MongoCode('getUqid()') , 'name' => "Sarah C."]);

我得到了类似的东西:

db.ads.find()
{ "_id" : ObjectId("51a34f8bf0774cac03000000"), "qid" : 17, "name" : "Sarah C." }
{ "_id" : ObjectId("51a34f8bf0774cac03000001"), "qid" : 20, "name" : "Michel D." }
{ "_id" : ObjectId("51a34f8bf0774cac03000002"), "qid" : 23, "name" : "Robert U." }

任何线索为什么 qid 被踩到 3 ?这应该意味着我收到了三个对我存储的函数的调用,对吗?

Any clue why qid is getting stepped by 3 ? It should mean that I received three call to my stored function right ?

预先感谢您的帮助,问候.

Thanks in advance for your help, Regards.

PS: 次要问题:是否仍然需要 NumberLong 来确保我们在内部 mongodb 存储中有 64 位无符号整数?有什么命令可以在 shell 中交叉检查吗?

PS: secondary question: are NumberLong still required to be sure we have 64bit unsigned integer in internal mongodb storage ? Any command to cross-check that in the shell ?

推荐答案

Cross-referencing this question with PHP-841.从 PHP 方面来看,您实际上是在 qid<中存储了一个 BSON 代码值/代码> 字段.您可以在从数据库取回结果或使用 mongodump 命令进行数据库导出时验证这一点.

Cross-referencing this question with PHP-841. From the PHP side of things, you're actually storing a BSON code value in the qid field. You can likely verify that when fetching results back from the database or doing a database export with the mongodump command.

问题在于 JS shell 在显示时错误地评估了代码类型,这就是执行 findAndModify 的地方.此修复程序应包含在后续服务器版本中.

The issue is with the JS shell wrongfully evaluating the code type upon display, and that's the point where findAndModify is executed. This fix should be included in a subsequent server release.

与此同时,Sammaye 建议从 PHP 调用 findAndModify 是此类功能的最佳选择.巧合的是,这也是 Doctrine MongoDB ODM 中所做的(参见:增量生成器).它确实需要到服务器的额外往返,但这是必要的,因为 MongoDB 没有在写入操作期间执行 JS 回调的工具.

In the meantime, Sammaye's suggestion to call findAndModify from PHP is the best option for this sort of functionality. Coincidentally, it is also what is done in Doctrine MongoDB ODM (see: IncrementGenerator). It does require an additional round trip to the server, but that is necessary since MongoDB has no facility for executing JS callbacks during a write operation.

如果最小化到 MongoDB 的往返次数是最重要的,您可以使用 MongoDB::execute() 并执行类似返回生成的 ID 作为命令响应的操作.当然,这通常是不可取的,JS 评估有其自身的注意事项.

If minimizing the round-trips to MongoDB is of utmost importance, you could insert the documents by executing server-side JS through PHP with MongoDB::execute() and do something like returning the generated ID(s) as the command response. Of course, that's generally not advisable and JS evaluation has its own caveats.

这篇关于插入槽中使用的存储函数 PHP 运行多次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆