Symfony QueryBuilder返回MongoDB游标而不是对象数组 [英] Symfony QueryBuilder returning MongoDB cursor instead of objects array

查看:293
本文介绍了Symfony QueryBuilder返回MongoDB游标而不是对象数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图构建一个自定义查询函数返回MongoDB文档对应的一些过滤器。我已将此函数创建到我的文档的特定存储库 User


  namespace LogAnalyzer\CoreBundle\Repository; 

使用Doctrine\ODM\MongoDB\DocumentRepository;

class UserRepository extends DocumentRepository
{
public function getUserTemp($ clauses = null)
{
/ *创建查询* /

$ query = $ this - > createQueryBuilder();

/ *添加子句* /

if($ clauses)
{
if(isset($ clauses ['id']))
$ query - >字段('id') - > equals($ clauses ['id']);

if(isset($ clauses ['firstName']))
$ query - >字段('firstName') - > equals($ clauses ['firstName']);

if(isset($ clauses ['lastName']))
$ query - >字段('lastName') - > equals($ clauses ['lastName']);

if(isset($ clauses ['email']))
$ query - >字段('email') - > equals($ clauses ['email']);

if(isset($ clauses ['password']))
$ query - >字段('password') - > equals($ clauses ['password']);
}

/ *返回* /

return $ query
- > getQuery()
- >执行();
}
}

这里是我的用户文档:


 命名空间LogAnalyzer \CoreBundle\Document; 

使用JsonSerializable;
使用Doctrine\ODM\MongoDB\Mapping\Annotations作为MongoDB;
使用Symfony \Component\Validator\Constraints as Assert;

/ **
* @ MongoDB \Document(repositoryClass =LogAnalyzer\CoreBundle\Repository\UserRepository)
* /
类用户实现JsonSerializable
{
/ **
* @ MongoDB \Id
* /
protected $ id;

/ **
* @ MongoDB \String
* /
protected $ firstName;

/ **
* @ MongoDB \String
* /
protected $ lastName;

/ **
* @ MongoDB \String
* /
protected $ email;

/ **
* @ MongoDB \String
* /
protected $ password;

...
}

私有函数使用查询函数:

 私有函数getUserAction()
{
$ manager = $这 - > get('doctrine_mongodb') - > getManager();
$ repository = $ manager - > getRepository('LogAnalyzerCoreBundle:User');

$ users = $ repository - > getUserTemp(array(
'firstName'=>'First'
));

return $ users;
}



当我运行函数时,我没有得到一个预期的对象数组但是 Doctrine\ODM\MongoDB\Cursor 代替。



我的错误在哪里? >

编辑:



我应该使用 - > toArray(false)



感谢。

解决方案>

您需要使用Eager MongoDB游标来迭代查询。我要编辑你的代码,使你更容易:

  class UserRepository extends DocumentRepository {
public function getUserTemp ($ clauses = null)
{
/ *创建查询* /

$ qb = $ this-> createQueryBuilder() - > eagerCursor

/ *添加子句* /

if($ clauses)
{
//这是一种初始化查询的方法,可以使用select或类似的东西
$ query = $ qb-> hydrate(true);

if(isset($ clauses ['id']))
$ query - >字段('id') - > equals($ clauses ['id']);

if(isset($ clauses ['firstName']))
$ query - >字段('firstName') - > equals($ clauses ['firstName']);

if(isset($ clauses ['lastName']))
$ query - >字段('lastName') - > equals($ clauses ['lastName']);

if(isset($ clauses ['email']))
$ query - >字段('email') - > equals($ clauses ['email']);

if(isset($ clauses ['password']))
$ query - >字段('password') - > equals($ clauses ['password']);
}

/ *返回* /

return $ query
- > getQuery()
- >执行();
}
}



现在您可以将结果作为对象

 私有函数getUserAction()
{
$ manager = $ this - > get('doctrine_mongodb') - > getManager();
$ repository = $ manager - > getRepository('LogAnalyzerCoreBundle:User');

$ users = $ repository - > getUserTemp(array(
'firstName'=>'First'
));
//这只是一个例子,但在这里你可以看到如何获取查询结果数据
foreach($ users as $ user){
$ data [] = $ user-> getFirstName();
}

return $ users;
}

这是最好的方法,有时调用toArray ,但不总是工作。


I am trying to build a custom querying function returning MongoDB documents corresponding to some filters. I have created this function into a specific repository for my document User:

namespace LogAnalyzer\CoreBundle\Repository;

use Doctrine\ODM\MongoDB\DocumentRepository;

class UserRepository extends DocumentRepository
{
    public function getUserTemp($clauses = null)
    {
        /* Create query */

        $query = $this -> createQueryBuilder();

        /* Add clauses */

        if($clauses)
        {
            if(isset($clauses['id']))
                $query -> field('id') -> equals($clauses['id']);

            if(isset($clauses['firstName']))
                $query -> field('firstName') -> equals($clauses['firstName']);

            if(isset($clauses['lastName']))
                $query -> field('lastName') -> equals($clauses['lastName']);

            if(isset($clauses['email']))
                $query -> field('email') -> equals($clauses['email']);

            if(isset($clauses['password']))
                $query -> field('password') -> equals($clauses['password']);
        }

        /* Return */

        return $query
            -> getQuery()
            -> execute();
    }
}

Here is the definition of my User document:

namespace LogAnalyzer\CoreBundle\Document;

use JsonSerializable;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @MongoDB\Document(repositoryClass="LogAnalyzer\CoreBundle\Repository\UserRepository")
 */
class User implements JsonSerializable
{
    /**
     * @MongoDB\Id
     */
    protected $id;

    /**
     * @MongoDB\String
     */
    protected $firstName;

    /**
     * @MongoDB\String
     */
    protected $lastName;

    /**
     * @MongoDB\String
     */
    protected $email;

    /**
     * @MongoDB\String
     */
    protected $password;

    ...
}

In my controller I have the private function using the querying function:

private function getUserAction()
{
    $manager = $this -> get('doctrine_mongodb') -> getManager();
    $repository = $manager -> getRepository('LogAnalyzerCoreBundle:User');

    $users = $repository -> getUserTemp(array(
        'firstName' => 'First'
    ));

    return $users;
}

When I run the function, I do not get an array of objects as expected but a Doctrine\ODM\MongoDB\Cursor instead.

Where is my error ?

EDIT:

Should I use -> toArray(false) ?

Thanks.

解决方案

You need the Eager MongoDB cursor to iterate queries. I'm gonna edit your code to make it easier for you:

class UserRepository extends DocumentRepository {
    public function getUserTemp($clauses = null)
    {
        /* Create query */

        $qb = $this->createQueryBuilder()->eagerCursor(true);

        /* Add clauses */

        if($clauses)
        {
            // It's a way to initialize the query, you can use a select or something similar
            $query = $qb->hydrate(true);

            if(isset($clauses['id']))
                $query -> field('id') -> equals($clauses['id']);

            if(isset($clauses['firstName']))
                $query -> field('firstName') -> equals($clauses['firstName']);

            if(isset($clauses['lastName']))
                $query -> field('lastName') -> equals($clauses['lastName']);

            if(isset($clauses['email']))
                $query -> field('email') -> equals($clauses['email']);

            if(isset($clauses['password']))
                $query -> field('password') -> equals($clauses['password']);
        }

        /* Return */

        return $query
            -> getQuery()
            -> execute();
    }
}

Now you can iterate the result with all results as objects inside.

private function getUserAction()
{
    $manager = $this -> get('doctrine_mongodb') -> getManager();
    $repository = $manager -> getRepository('LogAnalyzerCoreBundle:User');

    $users = $repository -> getUserTemp(array(
        'firstName' => 'First'
    ));
    //It's just an example, but here you can see how to get the query result data
    foreach($users as $user){
        $data[] = $user->getFirstName();
    }

    return $users;
}

It's the best way to do this, sometimes calling toArray() method is enough, but not always work.

这篇关于Symfony QueryBuilder返回MongoDB游标而不是对象数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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