【问题标题】:PHP MongoDB - Use of the aggregate command without the cursor option is deprecated. What?PHP MongoDB - 不推荐使用不带游标选项的聚合命令。什么?
【发布时间】:2017-10-04 18:49:25
【问题描述】:

我已经更新了 mongo,现在在日志中出现以下错误: 不推荐使用不带光标选项的聚合命令

Mongo 说我应该为聚合函数添加第二个 REQUIRED 参数,因为我目前的用法已被弃用。

我目前使用以下代码 PHP(现已弃用):

$this->db->{$collection}->aggregate($options);

并返回此格式:

{"result":[
    {
    "_id":"xxxxxx",
    "update":[
    {
    "firstUpdateTime":xxxxxx,
    "updateTime":xxxxxxx,
    }
    ],
    "media":[
    {
    "xxxx":{ ...

为了不使用已弃用的代码,我添加了新的第二个参数(但我不明白该放什么):

$this->db->{$collection}->aggregate($options, array('cursor' => array('batchSize' => 101)));

这会返回相同的信息,但会改变初始结构:

{"cursor":{
"id":{
"value":"xxxxxx"
},
"ns":"xxxxxx.instagram",
"firstBatch":[
{
"_id":"xxxxxx",
"update":[
{
"firstUpdateTime":xxxxxx,
"updateTime":xxxxxx,
}
],
"media":[
{
"xxxxxx":{ ...

更新后,Mongo 迫使我改变读取数据的方式。 我不明白我应该在名为“光标”的第二个参数中输入什么值...

我应该在第二个参数中输入什么? 我可以在不改变结果结构的情况下设置默认值吗?

文档: https://docs.mongodb.com/manual/reference/method/db.collection.aggregate/ http://php.net/manual/es/mongocollection.aggregate.php

更新:

如果我在函数中指示光标,我将不再收到错误。 但是在没有应用解决方案的情况下,我阅读了 LOG 并且随机出现了警告,我有一个代码我运行了几次,有时如果它报告提到的警告而其他人没有。

为什么?

【问题讨论】:

  • 您能否添加代码,包括带有和不带有光标选项的日志消息,以演示您在更新中提到的行为?
  • 转至此post 以供光标使用。

标签: php mongodb function php-mongodb


【解决方案1】:

当您向 MongoDB 查询某些内容并期望得到结果时,您将拥有一个名为 cursor变量,它只是指向您当前已阅读的文档的指针。它就像浏览器中的滚动条。

您可以指定应该将多少文档读入缓冲区batchSize,就像您对值1 所做的那样。

当您知道您希望阅读多少文件时,它很有用。当您只需要 10 个文档时,您可以使用 batchSize => 10 在单个网络数据包中获取所有这些文档。当指定batchSize => 5 时,需要更长的时间,因为它确实需要两个网络数据包到数据库才能获得预期的 10 个文档。

使用默认的batchSize 是安全的。

您可以尝试使用 foreach 迭代光标,就像文档中的示例一样:http://php.net/manual/en/class.mongocommandcursor.php

我不确定 php.net 文档是否是最新版本的 MongoDB 驱动程序。

【讨论】:

  • 到目前为止,我不必担心丢失数据,因为聚合会返回所有数据。我知道 batchSize 数字类似于查询的“限制”。如果我给你 101,你会得到什么?在我的结果示例中,“文档”是什么?谢谢! @DanFromGermany
  • @ephramd batchSize 对用户不可见,但会影响网络和内存,因为如果您的文档不适合缓冲区,客户端将调用服务器,例如“给我下一个 101文件”,所以这并不是真正的限制,因为您仍然可以获得所有文件。
【解决方案2】:

您必须使用返回光标行的aggregateCursor 而不是仅使用results

类似

默认情况下,第一批设置为 101 个结果。

$cur = $this->db->{$collection}->aggregateCursor($pipeline);

在 50 的聚合光标上为后续批次设置批次大小(您问题中的第二个参数)。如果您不使用以下选项,默认值将获取大约 4 MB。

$cur->batchSize( 50 );

您现在可以迭代并读取结果以获取所有文档。

服务器将在第一次循环迭代中获取初始(第一)批次的 101 个文档,然后在 102 次迭代中获取后续批次,并在其余批次中以 50 个间隔获取,直到您用尽游标。

foreach ( $cur as $result )
{
   echo $result['_id'], "\n";
}

要控制第一批的批量大小,您可以指定batchSize 作为光标选项,但通常不需要。

$cur = $this->db->{$collection}->aggregateCursor($pipeline, 'cursor' => [ 'batchSize' => 1 ]);

参考: https://derickrethans.nl/aggregation-cursor.html

【讨论】:

    【解决方案3】:

    根据最新的 MongoDB 手册,聚合操作已更改。

    aggregate without cursor

    MongoDB 3.4 不推荐使用不带游标的聚合命令 选项,除非管道包含解释选项。什么时候 使用聚合命令内联返回聚合结果, 使用默认批量大小光标指定光标选项:{} 或 在游标选项 cursor: { batchSize: }。

    您可以通过添加[ "cursor" => [ "batchSize" => 0 ] ] 为您的函数调用指定该参数,因为第二个参数将解决此问题。参考here

    游标参数的用法也可以参考这个SO question

    【讨论】:

      【解决方案4】:

      替换这个:
      $this->db->{$collection}->aggregate($options);

      通过添加游标数组使用以下代码。
      $this->db->{$collection}->aggregate($options,array('cursor'=>array('batchSize' => 1)));

      【讨论】:

        【解决方案5】:

        假设您使用的是最新的MongoDB PHP Library,您应该能够按照doc 中的说明传递'useCursor' => false 选项(默认为true)。

        【讨论】:

        • 感谢您的回复,但我没有使用 MongoDB PHP 库,我使用的是没有接口的库,并且此文档与我不兼容。我使用了消息中引用的内容,虽然这个有错误,因为根本没有更新。
        • 您当前使用的扩展名已经是deprecated。所以我认为没有任何简单的方法可以让它支持最新版本的 MongoDB。该文档建议将 MongoDB driver 与 MongoDB PHP 库结合使用
        【解决方案6】:

        驱动程序 mongo 已弃用,不支持最新的 PHP 主要版本(例如 PHP 7)。

        名为mongodbhttp://php.net/manual/en/set.mongodb.php的新驱动程序

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-28
          • 2018-10-23
          • 2012-05-04
          • 2010-11-18
          • 2011-03-05
          相关资源
          最近更新 更多