【问题标题】:Uncaught exception 'MongoDB\Driver\Exception\RuntimeException' with message 'An object representing an expression must have exactly one field:未捕获的异常“MongoDB\Driver\Exception\RuntimeException”和消息“表示表达式的对象必须只有一个字段:
【发布时间】:2018-06-12 09:17:06
【问题描述】:

我写了如下代码行

         $cursor = $this->collection->aggregate(array(
             array(
                   '$match' => array(
                                "_id" => new MongoDB\BSON\ObjectID($this->id)
                                )
                  ),
             array(
                  '$project' => array(
                  'AllotmentsDetails' => array(
                  '$filter' => array(
                  'input' => '$AllotmentsDetails',
                  'as' => 'allot',
                  'cond' => array(
                   '$and' => array(
                  '$lt' => array('$$allot.ToDate', new MongoDB\BSON\UTCDateTime((new DateTime())->getTimestamp() * 1000)),
                  '$eq' => array('$$allotment.RoomId', $this->RoomId)
                     )
                   )
                  )
                 ),
                )
              )
            ))->toArray();

它抛出错误消息“未捕获的异常 'MongoDB\Driver\Exception\RuntimeException' 和消息'表示表达式的对象必须只有一个字段:”

请帮忙!!!

【问题讨论】:

  • $filter 条件的$and 内的$lt$eq 上缺少包装array()。 PHP 认为这是{ "$and": { "$lt": [...], "$eq": [...] } },当你想要{ "$and": [{ "$lt": [...] },{ "$eq": [...] }] }。请记住,任何带有=> 的东西都意味着{} 是隐含的,没有它就是[]
  • 你能在例子中展示一下吗
  • 我试过像 '$and' => array( array('$lt' => array('$$allot.ToDate', new MongoDB\BSON\UTCDateTime((new DateTime() )->getTimestamp() * 1000))), array('$eq' => array('$$allotment.RoomId', $this->RoomId)) ) .........它不起作用
  • 请在代码段中显示为答案

标签: php mongodb aggregation-framework mongodb-php


【解决方案1】:

只是缺少数组符号并在一些错误的地方匹配:

$pipeline = array(
  array( '$match' => array(
    "_id" => new MongoDB\BSON\ObjectID($this->id)
  )),
  array('$project' => array(
    'AllotmentsDetails' => array(
      '$filter' => array(
        'input' => '$AllotmentsDetails',
        'as' => 'allotment',
        'cond' => array(
          '$and' => array(
            array('$lt' => array(
              '$$allotment.ToDate',
              new MongoDB\BSON\UTCDateTime((new DateTime())->getTimestamp() * 1000)
            )),
            array('$eq' => array('$$allotment.RoomId', $this->RoomId))
          )
        )
      )
    )
  ))
);

$cursor = $this->collection->aggregate($pipeline)->toArray();

或者因为我们处于现代世界,所以更容易阅读:

$pipeline = [
  ['$match' => [
    "_id" => new MongoDB\BSON\ObjectID($this->id)
  ]],
  ['$project' => [
    'AllotmentsDetails' => [
      '$filter' => [
        'input' => '$AllotmentsDetails',
        'as' => 'allotment',
        'cond' => [
          '$and' => [
            ['$lt' => [
              '$$allotment.ToDate',
              new MongoDB\BSON\UTCDateTime((new DateTime())->getTimestamp() * 1000)
            ]],
            ['$eq' => ['$$allotment.RoomId', $this->RoomId] ]
          ]
        ]
      ]
    ]
  ]]
];

$cursor = $this->collection->aggregate($pipeline)->toArray();

我建议使用更好的编辑器,并在您的数据结构上使用json_encode(),以检查生成的 JSON 是否与您在文档中看到的示例相匹配。

【讨论】:

    猜你喜欢
    • 2019-09-05
    • 2013-12-08
    • 1970-01-01
    • 2013-08-24
    • 2012-04-25
    • 1970-01-01
    • 2010-10-24
    • 1970-01-01
    • 2017-08-31
    相关资源
    最近更新 更多