2012-12-02 21:58:15 +04:00
|
|
|
Ordering To-Many Associations
|
|
|
|
-----------------------------
|
2012-01-28 03:49:37 +04:00
|
|
|
|
2012-06-13 02:36:40 +04:00
|
|
|
There are use-cases when you'll want to sort collections when they are
|
2012-01-28 03:49:37 +04:00
|
|
|
retrieved from the database. In userland you do this as long as you
|
|
|
|
haven't initially saved an entity with its associations into the
|
|
|
|
database. To retrieve a sorted collection from the database you can
|
|
|
|
use the ``@OrderBy`` annotation with an collection that specifies
|
|
|
|
an DQL snippet that is appended to all queries with this
|
|
|
|
collection.
|
|
|
|
|
|
|
|
Additional to any ``@OneToMany`` or ``@ManyToMany`` annotation you
|
|
|
|
can specify the ``@OrderBy`` in the following way:
|
|
|
|
|
2013-04-03 20:31:07 +04:00
|
|
|
.. configuration-block::
|
|
|
|
|
|
|
|
.. code-block:: php
|
|
|
|
|
|
|
|
<?php
|
|
|
|
/** @Entity **/
|
|
|
|
class User
|
|
|
|
{
|
|
|
|
// ...
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @ManyToMany(targetEntity="Group")
|
|
|
|
* @OrderBy({"name" = "ASC"})
|
|
|
|
**/
|
|
|
|
private $groups;
|
|
|
|
}
|
|
|
|
|
|
|
|
.. code-block:: xml
|
|
|
|
|
|
|
|
<doctrine-mapping>
|
|
|
|
<entity name="User">
|
|
|
|
<many-to-many field="groups" target-entity="Group">
|
|
|
|
<order-by>
|
|
|
|
<order-by-field name="name" direction="ASC" />
|
|
|
|
</order-by>
|
|
|
|
</many-to-many>
|
|
|
|
</entity>
|
|
|
|
</doctrine-mapping>
|
|
|
|
|
|
|
|
.. code-block:: yaml
|
|
|
|
|
|
|
|
User:
|
|
|
|
type: entity
|
|
|
|
manyToMany:
|
|
|
|
groups:
|
|
|
|
orderBy: { 'name': 'ASC' }
|
|
|
|
targetEntity: Group
|
|
|
|
joinTable:
|
|
|
|
name: users_groups
|
|
|
|
joinColumns:
|
|
|
|
user_id:
|
|
|
|
referencedColumnName: id
|
|
|
|
inverseJoinColumns:
|
|
|
|
group_id:
|
|
|
|
referencedColumnName: id
|
2012-06-20 14:41:20 +04:00
|
|
|
|
2012-01-28 03:49:37 +04:00
|
|
|
The DQL Snippet in OrderBy is only allowed to consist of
|
|
|
|
unqualified, unquoted field names and of an optional ASC/DESC
|
|
|
|
positional statement. Multiple Fields are separated by a comma (,).
|
|
|
|
The referenced field names have to exist on the ``targetEntity``
|
|
|
|
class of the ``@ManyToMany`` or ``@OneToMany`` annotation.
|
|
|
|
|
|
|
|
The semantics of this feature can be described as follows.
|
|
|
|
|
|
|
|
|
|
|
|
- ``@OrderBy`` acts as an implicit ORDER BY clause for the given
|
|
|
|
fields, that is appended to all the explicitly given ORDER BY
|
|
|
|
items.
|
|
|
|
- All collections of the ordered type are always retrieved in an
|
|
|
|
ordered fashion.
|
|
|
|
- To keep the database impact low, these implicit ORDER BY items
|
|
|
|
are only added to an DQL Query if the collection is fetch joined in
|
|
|
|
the DQL query.
|
|
|
|
|
|
|
|
Given our previously defined example, the following would not add
|
|
|
|
ORDER BY, since g is not fetch joined:
|
|
|
|
|
|
|
|
.. code-block:: sql
|
|
|
|
|
|
|
|
SELECT u FROM User u JOIN u.groups g WHERE SIZE(g) > 10
|
|
|
|
|
|
|
|
However the following:
|
|
|
|
|
|
|
|
.. code-block:: sql
|
|
|
|
|
|
|
|
SELECT u, g FROM User u JOIN u.groups g WHERE u.id = 10
|
|
|
|
|
|
|
|
...would internally be rewritten to:
|
|
|
|
|
|
|
|
.. code-block:: sql
|
|
|
|
|
|
|
|
SELECT u, g FROM User u JOIN u.groups g WHERE u.id = 10 ORDER BY g.name ASC
|
|
|
|
|
2012-04-13 00:22:06 +04:00
|
|
|
You can reverse the order with an explicit DQL ORDER BY:
|
2012-01-28 03:49:37 +04:00
|
|
|
|
|
|
|
.. code-block:: sql
|
|
|
|
|
|
|
|
SELECT u, g FROM User u JOIN u.groups g WHERE u.id = 10 ORDER BY g.name DESC
|
|
|
|
|
|
|
|
...is internally rewritten to:
|
|
|
|
|
|
|
|
.. code-block:: sql
|
|
|
|
|
|
|
|
SELECT u, g FROM User u JOIN u.groups g WHERE u.id = 10 ORDER BY g.name DESC, g.name ASC
|
|
|
|
|
|
|
|
|