无法规范化查询:BadValue $or/$and/$nor 条目需要是完整对象 - Doctrine

问题描述 投票:0回答:3

我正在尝试隐藏此查询

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

遵循教义,但我遇到了这个错误。

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();

这段代码有什么问题,有人可以给我任何提示吗?

php mongodb symfony doctrine-orm doctrine-odm
3个回答
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)
    )
);

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() 的作用很重要,它只是一个简单的工厂方法,用于创建一个与调用它的构建器对象没有任何关系的表达式对象。

$builder->expr()

相当于

(new Expr())

addAnd 和 addOr 方法将所有内容整齐地联系在一起。 expr() 方法就在那里,因此 querybuilder 的维护者可以担心表达式的类和依赖项注入,但对于不太了解构建器的人来说,它可能会混淆 expr() 方法的重要性。


0
投票

我在应用 $or 和 $ 时遇到了类似的不良价值问题,并且一起仅举一个我的代码示例,它可能会帮助您在解决 $condition 数组时解决它:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.