无法规范化查询:BadValue $或/ $和/ $条目也需要是完整对象 - Doctrine

时间:2017-03-24 03:45:23

标签: php mongodb symfony doctrine-orm doctrine-odm

我试图隐瞒这个查询

db.getCollection('queues').find({
    $and:[
        {queue: 'testo'},
        {$or: [
            {$and: [{reserved_at: null}, {available_at:{'$lte':1490323024}}]},
            {reserved_at:{'$lte':1490323024}}
        ]}
    ]
});

to doctrine但我收到了这个错误。

Can't canonicalize query: BadValue $or/$and/$nor entries need to be full objects.

这就是我的尝试。

$builder = $this->get('doctrine_mongodb')->getManager()->createQueryBuilder('AppBundle:Ticket');

$builder->findAndUpdate()->addAnd([
    $builder->field('queue')->equals($queue),
    $builder->addOr([
        $builder->addAnd([
            $builder->field('reservedAt')->equals(null),
            $builder->field('availableAt')->lte($currentTime)
        ]),
        $builder->field('reservedAt')->lte($expiration)
    ])
])
->sort('id', 'ASC')
->limit(1)
->field('reservedAt')->set($currentTime->getTimestamp());

$job = $builder->getQuery()->execute()->toArray();

这段代码有什么不对,有人可以给我任何提示。

3 个答案:

答案 0 :(得分:0)

我不熟悉Doctrine的ODM,但由于它有一个QueryBuilder,我假设它还有一个类似于ORM-QueryBuilder的方法expr()

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/query-builder.html#the-expr-class

使用expr-class,您可以构建如下的嵌套查询:

->where(
    $builder->expr()->or(
        $builder->expr()->and(
            $builder->expr()->isNull('reservedAt'),
            $builder->expr()->lte('availableAt', $currentTime),
        ),
        $builder->expr()->lte('reservedAt', $expirationDate)
    )
);

答案 1 :(得分:0)

这是因为您将嵌套条件添加到原始QueryBuilder对象中。即使你正在使用带有嵌套参数的addAnd和addOr方法,你仍然会改变顶层构建器,所以它会对你尝试对这些条件做些什么感到困惑。

尝试这样的事情:

$builder
    ->findAndUpdate()
    ->addAnd([
        $builder->expr()->field('queue')->equals($queue),
        $builder->expr()->addOr([
            $builder->expr()->addAnd([
                $builder->expr()->field('reservedAt')->equals(null),
                $builder->expr()->field('availableAt')->lte($currentTime)
            ]),
            $builder->expr()->field('reservedAt')->lte($expiration)
        ])
    ]);

了解expr()的作用非常重要,它只不过是一个简单的工厂方法,它创建一个Expression对象,其 nothing 与调用它的构建器对象有关。

$builder->expr()

相当于

(new Expr())

这是addAnd和addOr方法,将所有内容整齐地组合在一起。 expr()方法就在那里,所以querybuilder的维护者可以担心你的Expression的类和依赖注入,但对于那些不太熟悉构建器的人来说,它可以模糊expr()方法的重要性。

答案 2 :(得分:0)

我有类似的价值问题,应用$或$和一起只是举一个我的代码的例子它可能会帮助你解决$ condition数组时解决:

$condition['$or'] = [
            ['assigned_to' => (int)$id,
                'type' => "customer",
                'assigned_date' => ['$gte'=>$mDate],
            ],
            ['assigned_to' => 0,
                'read' => 'no',
                'type' => "customer",
                'assigned_date' => ['$gte'=>$mDate],
            ]
        ];

仅在形成Array时出现问题。我使用Mongo和PHP类。