মতবাদ কোয়েরি বিল্ডারে সারিগুলি গণনা করুন


197

আমি একটি কোয়েরি তৈরির জন্য ডক্ট্রিনের কোয়েরি বিল্ডার ব্যবহার করছি এবং আমি কোয়েরি থেকে ফলাফলের মোট গণনা পেতে চাই।

$repository = $em->getRepository('FooBundle:Foo');

$qb = $repository->createQueryBuilder('n')
        ->where('n.bar = :bar')
        ->setParameter('bar', $bar);

$query = $qb->getQuery();

//this doesn't work
$totalrows = $query->getResult()->count();

মোট সারি পেতে আমি এই ক্যোয়ারীতে একটি সংখ্যা চালাতে চাই, তবে আসল ফলাফলটি ফিরিয়ে আনব না। (এই গণনা ক্যোয়ারির পরে, আমি পৃষ্ঠাগুলির জন্য সর্বোচ্চ ফলাফলের সাথে ক্যোয়ারীটি আরও সংশোধন করতে যাচ্ছি))


1
আপনি কেবল ফলাফলের সংখ্যাটি ফিরিয়ে দিতে চান? আপনার কোড খুব পরিষ্কার নয়। getQuery () কাজ করে না কেন?
jere


3
@ স্টেফান এটি এখন ওআরএম এর অংশ। docs.doctrine-project.org/en/latest/tutorials/pagination.html
ইউজিন

উত্তর:


474

কিছুটা এইরকম:

$qb = $entityManager->createQueryBuilder();
$qb->select('count(account.id)');
$qb->from('ZaysoCoreBundle:Account','account');

$count = $qb->getQuery()->getSingleScalarResult();

কিছু লোকেরা মনে করেন যে কেবল সোজা ডিকিউএল ব্যবহার না করেই এক্সপ্রেশনগুলি আরও ভাল better একটি এমনকি চার বছরের পুরানো উত্তর সম্পাদনা করতে এতদূর গিয়েছিল। আমি তার সম্পাদনাটি ঘুরিয়ে দিয়েছি। চিত্রে যান.


তিনি পূর্বাভাস ( bar = $bar);) ব্যতীত গণনা জিজ্ঞাসা করেননি
জোভান পেরোভিক

4
তিনি আপনার উত্তর গ্রহণ করেছেন তাই আমি অনুমান করি যে সবকিছু ঠিক আছে। আমি এই ছাপে ছিলাম যে তিনি কেবলমাত্র আমার উদাহরণ দেখায় এমন সারিগুলি পুনরুদ্ধার করার জন্য ওভারহেড ছাড়াই একটি গণনা চেয়েছিলেন। শর্তগুলি যুক্ত করা যায়নি কেন এর অবশ্যই কোনও কারণ নেই।
সেরাড

50
GetSingleScalarResult () ব্যবহারের জন্য +1। ব্যবহার count()উপর $query->getResult()আসলে ক্যোয়ারী ফলাফল শূণ্য (যা এটা কি তিনি করছে না চান)। আমি মনে করি এটি উত্তর গ্রহণ করা উচিত
jere

18
সর্বাধিক বহনযোগ্য উপায় হ'ল$qb->select($qb->expr()->count('account.id'))
ওয়েববিডেভ

1
আমাকে select('count(account.id)')পরিবর্তে কেন ব্যবহার করতে হবে তা কি কেউ ব্যাখ্যা করতে পারেন select('count(account)')?
Stepan Yudin

51

এখানে ক্যোয়ারী ফর্ম্যাট করার অন্য উপায়:

return $repository->createQueryBuilder('u')
            ->select('count(u.id)')
            ->getQuery()
            ->getSingleScalarResult();

অনর্গল ইন্টারফেস ব্যবহার করা একটি পৃথক পদ্ধতি যা আপনি স্থির প্রশ্নগুলি লেখার ইচ্ছুক ক্ষেত্রে খুব সহায়ক। যদি টগল করার প্রয়োজন হয় যেখানে উদাহরণস্বরূপ নিজস্ব পদ্ধতিতে প্রতিটি পদ্ধতি চালানোর ক্ষেত্রে এর সুবিধাগুলিও রয়েছে।
বারবিউইসক্রিউ

3
আপনি এটি লিখতে পারেনreturn ($qb = $repository->createQueryBuilder('u'))->select($qb->expr()->count('u.id'))->getQuery()->getSingleScalarResult();
বার্হ

25

ডাটাবেসের সাথে কাজ করার সমস্ত যুক্তি সঞ্চিতাগুলিতে স্থানান্তর করা ভাল।

সুতরাং নিয়ামক আপনি লিখুন

/* you can also inject "FooRepository $repository" using autowire */
$repository = $this->getDoctrine()->getRepository(Foo::class);
$count = $repository->count();

এবং ভিতরে Repository/FooRepository.php

public function count()
{
    $qb = $repository->createQueryBuilder('t');
    return $qb
        ->select('count(t.id)')
        ->getQuery()
        ->getSingleScalarResult();
}

$qb = ...আপনি যদি জটিল মত প্রকাশ করতে চান সে ক্ষেত্রে পৃথক সারিতে চলে যাওয়া ভাল

public function count()
{
    $qb = $repository->createQueryBuilder('t');
    return $qb
        ->select('count(t.id)')
        ->where($qb->expr()->isNotNull('t.fieldName'))
        ->andWhere($qb->expr()->orX(
            $qb->expr()->in('t.fieldName2', 0),
            $qb->expr()->isNull('t.fieldName2')
        ))
        ->getQuery()
        ->getSingleScalarResult();
}

আপনার অনুসন্ধানের ফলাফলটি ক্যাশে করার বিষয়েও ভাবুন - http://symfony.com/doc/current/references/configration/doctrine.html#caching-drivers

public function count()
{
    $qb = $repository->createQueryBuilder('t');
    return $qb
        ->select('count(t.id)')
        ->getQuery()
        ->useQueryCache(true)
        ->useResultCache(true, 3600)
        ->getSingleScalarResult();
}

কিছু সাধারণ ক্ষেত্রে EXTRA_LAZYসত্তা সম্পর্ক ব্যবহার করা ভাল
http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/tutorials/extra-lazy-associations.html


17

আপনি একটি আরো জটিল ক্যোয়ারী, সঙ্গে গণনা করার প্রয়োজন হলে groupBy, havingইত্যাদি ... আপনি এর থেকে ধার নিতে পারেন Doctrine\ORM\Tools\Pagination\Paginator:

$paginator = new \Doctrine\ORM\Tools\Pagination\Paginator($query);
$totalRows = count($paginator);

8
দরকারী, তবে দয়া করে নোট করুন: এই সমাধানটি একটি একক সত্তা সম্পর্কিত প্রশ্নের জন্য কাজ করবে- জটিল নির্বাচনী বিবৃতি সহ, এটি কেবল কাজ করতে অস্বীকার করবে।
পাওলো স্টেফান

এই সমাধানটি অতিরিক্ত SELECT COUNT(*) AS dctrn_count FROM (_ORIGINAL_SQL_) dctrn_result) dctrn_table
ক্যোরির

ag paginator-> getTotalItemCount () এর সমাধানও হবে
cwisperer

11

যেহেতু সরাসরি থেকে পদ্ধতি Doctrine 2.6ব্যবহার করা সম্ভব । বিস্তারিত জানার জন্য লিঙ্কটি দেখুন।count()EntityRepository

https://github.com/doctrine/doctrine2/blob/77e3e5c96c1beec7b28443c5b59145eeadbc0baf/lib/Doctrine/ORM/EntityRepository.php#L161


হ্যাঁ, এটি দুর্দান্ত সমাধান হিসাবে দেখায় এবং আরও সাধারণ ক্ষেত্রে কাজ করে (আপনি গণনা ফিল্টার করার জন্য মানদণ্ডটি পাস করতে পারেন), তবে আমি এটির সাথে মেলামেশার সাথে কাজ করার ব্যবস্থা করতে পারি নি (সমিতি দ্বারা ফিল্টারিং)। সম্পর্কিত পোস্টটি এখানে দেখুন: github.com/doctrine/orm/issues/6290
উইল্ট

6

গ্রুপিং, ইউনিয়ন এবং স্টাফ নিয়ে কাজ করার উদাহরণ।

সমস্যা:

 $qb = $em->createQueryBuilder()
     ->select('m.id', 'rm.id')
     ->from('Model', 'm')
     ->join('m.relatedModels', 'rm')
     ->groupBy('m.id');

এটির সম্ভাব্য সমাধানটি কার্যকর করার জন্য কাস্টম হাইড্রেটর এবং 'কাস্টম আউটপুট ওয়াকার হিন্ট' নামে পরিচিত এই অদ্ভুত জিনিসটি ব্যবহার করা:

class CountHydrator extends AbstractHydrator
{
    const NAME = 'count_hydrator';
    const FIELD = 'count';

    /**
     * {@inheritDoc}
     */
    protected function hydrateAllData()
    {
        return (int)$this->_stmt->fetchColumn(0);
    }
}
class CountSqlWalker extends SqlWalker
{
    /**
     * {@inheritDoc}
     */
    public function walkSelectStatement(AST\SelectStatement $AST)
    {
        return sprintf("SELECT COUNT(*) AS %s FROM (%s) AS t", CountHydrator::FIELD, parent::walkSelectStatement($AST));
    }
}

$doctrineConfig->addCustomHydrationMode(CountHydrator::NAME, CountHydrator::class);
// $qb from example above
$countQuery = clone $qb->getQuery();
// Doctrine bug ? Doesn't make a deep copy... (as of "doctrine/orm": "2.4.6")
$countQuery->setParameters($this->getQuery()->getParameters());
// set custom 'hint' stuff
$countQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, CountSqlWalker::class);

$count = $countQuery->getResult(CountHydrator::NAME);

7
আমি বরং সেই রুবে গোল্ডবার্গ কোডটি ডিল করার চেয়ে কেবল একটি দেশীয় ক্যোয়ারী লিখব।
keyboardSmasher

শিট্টি সাইমফনি এটির একটি দুর্দান্ত উদাহরণ: একটি বেসিক প্রতিদিনের এসকিউএল-কাউন্টের মতো সাধারণ কিছু হ'ল সম্পূর্ণ জটিল স্ব-লিখিত জিনিসগুলির সাথে সমাধান করা দরকার ... বাহ, মানে, কেবল বাহ! এখনও এই উত্তরের জন্য সার্জি ধন্যবাদ!
স্লিক

4

যে সমস্ত লোকেরা কেবলমাত্র ডক্ট্রাইন ডিবিএল ব্যবহার করছেন এবং ডক্ট্রিন ওআরএম নয়, তারা getQuery()পদ্ধতিটিতে অ্যাক্সেস করতে পারবেন না কারণ এটি বিদ্যমান নেই। তাদের নিম্নলিখিতগুলির মতো কিছু করা দরকার।

$qb = new QueryBuilder($conn);
$count = $qb->select("count(id)")->from($tableName)->execute()->fetchColumn(0);

4

কিছু সংখ্যক আইটেম (অফসেট) এর পরে আইটেম গণনা করার জন্য, এই ক্ষেত্রে-qb-> setFirstResults () প্রয়োগ করা যাবে না, কারণ এটি কোয়েরির শর্ত হিসাবে নয়, তবে নির্বাচিত আইটেমগুলির জন্য সন্ধানের ফলাফলের অফসেট হিসাবে ( যেমন সেটফার্সআরসাল্ট মোটেও COUNT এর সাথে টগডারে ব্যবহার করা যায় না)। সুতরাং আইটেমগুলি গণনা করতে, যা বাকি আছে আমি কেবল নিম্নলিখিতগুলি করেছি:

   //in repository class:
   $count = $qb->select('count(p.id)')
      ->from('Products', 'p')
      ->getQuery()
      ->getSingleScalarResult();

    return $count;

    //in controller class:
    $count = $this->em->getRepository('RepositoryBundle')->...

    return $count-$offset;

এটি করার জন্য আরও পরিষ্কার উপায় কেউ জানেন?


0

আপনার সংগ্রহস্থলটিতে নিম্নলিখিত পদ্ধতিটি যুক্ত করা $repo->getCourseCount()আপনার নিয়ন্ত্রণকারী থেকে কল করার অনুমতি দেয় ।

/**
 * @return array
 */
public function getCourseCount()
{
    $qb = $this->getEntityManager()->createQueryBuilder();

    $qb
        ->select('count(course.id)')
        ->from('CRMPicco\Component\Course\Model\Course', 'course')
    ;

    $query = $qb->getQuery();

    return $query->getSingleScalarResult();
}

0

আপনি কাউন্ট ফাংশন ব্যবহার করে ডেটা সংখ্যাও পেতে পারেন।

$query = $this->dm->createQueryBuilder('AppBundle:Items')
                    ->field('isDeleted')->equals(false)
                    ->getQuery()->count();
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.