FindAll डॉक्ट्रिन की विधि को कैसे सॉर्ट करें


111

मैं Doctrine के दस्तावेज पढ़ रहा हूं, लेकिन मैं findAll () परिणाम को सॉर्ट करने का एक तरीका नहीं खोज पाया हूं।

मैं symfony2 + सिद्धांत का उपयोग कर रहा हूं, यह वह कथन है जो मैं अपने नियंत्रक के अंदर उपयोग कर रहा हूं:

$this->getDoctrine()->getRepository('MyBundle:MyTable')->findAll();

लेकिन मैं चाहता हूं कि परिणामों का आदेश उपयोगकर्ता नाम के आरोही द्वारा दिया जाए।

मैं इस तरह एक तर्क के रूप में एक सरणी पारित करने की कोशिश कर रहा हूँ:

findAll( array('username' => 'ASC') );

लेकिन यह काम नहीं करता है (यह या तो शिकायत नहीं करता है)।

क्या DQL क्वेरी के निर्माण के बिना ऐसा करने का कोई तरीका है?

जवाबों:


229

जैसा कि @Lighthart दिखाया गया है, हाँ यह संभव है, हालाँकि यह नियंत्रक में महत्वपूर्ण वसा जोड़ता है और DRY नहीं है।

आपको वास्तव में इकाई रिपॉजिटरी में अपनी खुद की क्वेरी को परिभाषित करना चाहिए, यह सरल और सर्वोत्तम अभ्यास है।

use Doctrine\ORM\EntityRepository;

class UserRepository extends EntityRepository
{
    public function findAll()
    {
        return $this->findBy(array(), array('username' => 'ASC'));
    }
}

फिर आपको रिपॉजिटरी में प्रश्नों की तलाश के लिए अपनी इकाई को बताना होगा:

/**
 * @ORM\Table(name="User")
 * @ORM\Entity(repositoryClass="Acme\UserBundle\Entity\Repository\UserRepository")
 */
class User
{
    ...
}

अंत में, अपने नियंत्रक में:

$this->getDoctrine()->getRepository('AcmeBundle:User')->findAll();

2
यह मेरा एक बेहतर दृष्टिकोण है, लेकिन आप dql लिख रहे होंगे; मेरी विधि कम dql है और इसलिए ओपी की बाधा का जवाब देता है। सच कहूँ तो, dql के डर को दूर किया जाना चाहिए। यदि संभव हो तो इस विधि का उपयोग मेरी पसंद में करें।
लाइटहार्ट

अच्छी तरह से यह dql का डर नहीं है, और इस उत्तर को पढ़ने से पहले मैंने अंततः इसे प्राप्त करने के लिए DQL का उपयोग किया था, लेकिन मैं शुरुआत में DQL का उपयोग नहीं करना चाहता था क्योंकि मेरे नियंत्रक में कोई DQL नहीं था, और मैं छड़ी करना चाहता था कोड शैली नियंत्रक पहले से ही था। यह समाधान मेरे लिए वास्तव में अच्छा काम करता है!
ILikeTacos

1
या बस: $ इस-> getDoctrine () -> getRepository ('AcmeBundle: उपयोगकर्ता') -> findBy (सरणी) (, सरणी ('उपयोगकर्ता नाम' => 'ASC'));
बेन्जी_एक्स 23०

1
@ Benji_X80 जबकि एक-लाइनर निश्चित रूप से छोटा है, यह बिल्कुल नहीं है। FindAll पद्धति रिपॉजिटरी की है, नियंत्रक की नहीं।
पियर-ल्यूक गेंड्रेउ

1
क्या आप टिप्पणियों का उपयोग करने के अलावा किसी अन्य तरीके से कस्टम रिपॉजिटरी में प्रश्नों को देखने के लिए इकाई बता सकते हैं? यह सबसे भयानक प्रोग्रामिंग अभ्यास है जिसे मैंने कभी देखा है
सेजनस

81
$this->getDoctrine()->getRepository('MyBundle:MyTable')->findBy([], ['username' => 'ASC']);


20

कभी-कभी स्रोत कोड को देखना उपयोगी होता है।

उदाहरण के लिए findAllकार्यान्वयन बहुत सरल है ( vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php):

public function findAll()
{
    return $this->findBy(array());
}

इसलिए हम देखते हैं findByऔर पाते हैं कि हमें क्या चाहिए ( orderBy)

public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)

6

यह मेरे लिए काम करता है:

$entities = $em->getRepository('MyBundle:MyTable')->findBy(array(),array('name' => 'ASC'));

पहले सरणी को खाली रखने से सभी डेटा वापस आ जाते हैं, यह मेरे मामले में काम करता है।



5

आपको एक मानदंड का उपयोग करने की आवश्यकता है, उदाहरण के लिए:

<?php

namespace Bundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\Common\Collections\Criteria;

/**
* Thing controller
*/
class ThingController extends Controller
{
    public function thingsAction(Request $request, $id)
    {
        $ids=explode(',',$id);
        $criteria = new Criteria(null, <<DQL ordering expression>>, null, null );

        $rep    = $this->getDoctrine()->getManager()->getRepository('Bundle:Thing');
        $things = $rep->matching($criteria);
        return $this->render('Bundle:Thing:things.html.twig', [
            'entities' => $things,
        ]);
    }
}

4

सिम्फनी में findBy मेथड दो मापदंडों को स्वीकार करता है। पहला फ़ील्ड उन फ़ील्ड्स का है, जिन पर आप खोज करना चाहते हैं और दूसरा सरणी सॉर्ट फ़ील्ड और उसका क्रम है

public function findSorted()
    {
        return $this->findBy(['name'=>'Jhon'], ['date'=>'DESC']);
    }

क्या आप अपने बहुत ही संक्षिप्त उत्तर में कुछ स्पष्टीकरण जोड़ सकते हैं?
निको हासे

यह एक शक्तिशाली छोटा जवाब है। विस्तृत - व्याख्या करें ... संपादित करें
पॉल

यह सही जवाब था! findBy (array (), array ('fieldname' => 'ASC') यह सभी को मिल जाएगा और इंगित की गई दिशा के साथ फ़ील्ड पर सॉर्ट करेगा।
रॉबर्ट सेलर

2

आप एक सरणी पुनरावृत्त का उपयोग करके एक मौजूदा ArrayCollection सॉर्ट कर सकते हैं।

$ संग्रह मानकर आपका ArrayCollection findAll द्वारा लौटाया गया है ()

$iterator = $collection->getIterator();
$iterator->uasort(function ($a, $b) {
    return ($a->getPropery() < $b->getProperty()) ? -1 : 1;
});
$collection = new ArrayCollection(iterator_to_array($iterator));

FindAllOrderBy () विधि बनाने के लिए इसे आसानी से एक फ़ंक्शन में बदल दिया जा सकता है जिसे आप अपने भंडार में डाल सकते हैं।


4
यहाँ आपकी क्या बात है? इसके लिए पर्याप्त उपयोग के मामले हैं ... यानी PHP में पहले से ही संग्रहित संग्रह को छांटना हमेशा एक और mysql क्वेरी को छांटने के लिए प्रदर्शन करने की तुलना में तेज़ होता है! कल्पना कीजिए कि आपको एक पेज पर दो अलग-अलग सॉर्टिंग शैलियों में समान संग्रह डेटा का उत्पादन करने की आवश्यकता है ...
निकोलाई फ्रोइलिच

2
सामान्य तौर पर, ऑर्डर की गई क्वेरी वापस करना डेटाबेस का काम होना चाहिए। OTOH, इस तकनीक में अधिक शामिल मामलों nifr उल्लेखों के लिए प्रयोज्यता है।
लाइटहार्ट

2

इसे इस्तेमाल करे:

$em = $this->getDoctrine()->getManager();

$entities = $em->getRepository('MyBundle:MyTable')->findBy(array(), array('username' => 'ASC'));

1

मैं उस समाधान के लिए एक विकल्प का उपयोग करता हूं जिसने निफ़र लिखा था।

$resultRows = $repository->fetchAll();
uasort($resultRows, function($a, $b){
    if ($a->getProperty() == $b->getProperty()) {
        return 0;
    }
    return ($a->getProperty()< $b->getProperty()) ? -1 : 1;
});

यह ORDER BY क्लॉज की तुलना में तेज है , और Iterator के ओवरहेड के बिना।


कृपया अपने उत्तर में कुछ और स्पष्टीकरण जोड़ें। डेटाबेस स्तर पर इसे करने की तुलना में आपके एप्लिकेशन में छंटनी कैसे तेज हो सकती है?
निको हसे

0

इस तरह EntityRepository में डिफ़ॉल्ट findAll फ़ंक्शन को संशोधित करें:

public function findAll( array $orderBy = null )
{
    return $this->findBy([], $orderBy);
}

इस तरह आप किसी भी डेटा तालिका के लिए क्वेरी को सॉर्ट करने के विकल्प के साथ किसी भी क्वेरी पर '' findAll '' का उपयोग कर सकते हैं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.