Доктрина встраивает документ в порядок по ключу

У меня есть документ mongodb в symfony2 с вложенным документом:

/**
* @MongoDB\EmbedMany(targetDocument="Restriction")
*/
private $restrictions = array();

public function __construct()
{
$this->restrictions = new \Doctrine\Common\Collections\ArrayCollection();
}

Ограничительный документ имеет два свойства. from_pos и длина. Я хочу, чтобы этот массив всегда сортировался по from_pos, поэтому во всем приложении я всегда буду уверен, что этот список отсортирован.

Есть ли простой способ сделать это автоматически? Я имею в виду, вызвать функцию addRestriction, и она будет автоматически сохранена в базе данных mongodb, отсортированной по ключу, который я хочу.

В настоящее время функция addRestriction просто добавляет новый документ в конец списка.

/**
* Add restriction
*
* @param MyBundle\Document\Restriction $restriction
*/
public function addRestriction(\MyBundle\Document\Restriction $restriction)
{
$this->restrictions[] = $restriction;
}

Я мог бы обновить эту функцию, чтобы вставить ограничение в нужную позицию, но я хотел бы знать, есть ли самый простой способ.

0

Решение

Решение заключается в использовании пользовательских коллекций.

http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/custom-collections.html

Это класс SortedCollection, который я разработал. При добавлении элемента просто поместите его в правильное положение и нарежьте другие элементы.

<?php

use Doctrine\Common\Collections\ArrayCollection;

/**
* Array collection with elements alwais in order
*/
class SortedCollection extends ArrayCollection{

/**
* Interrnal flag to avoid recursive call to reindex function while reindexing
* @var boolean
*/
protected $reindexing = false;

public function add($value){
$it = $this->getIterator();
while($it->valid() && $it->current()->compareTo($value) < 0){
$it->next();
}

// slice elements
$prev = $value;
while ($it->valid()){
// Save current element
$aux = $it->current();

// Add previous element
$this->offsetSet($it->key(), $prev);

// Set previous element to current for next iteration
$prev = $aux;
$it->next();
}

// Add final element
parent::add($prev);

return true;
}
}

А в документе просто установите класс SortedCollection в конструкторе.

<?php

class MyDocument
{
/**
* @MongoDB\EmbedMany(
*     collectionClass="SortedCollection",
*     targetDocument="...."* )
*/
private $sorted_list = array();

public function __construct()
{
$this->sorted_list = new SortedCollection();
}
}
0

Другие решения

Других решений пока нет …