У меня есть документ 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;
}
Я мог бы обновить эту функцию, чтобы вставить ограничение в нужную позицию, но я хотел бы знать, есть ли самый простой способ.
Решение заключается в использовании пользовательских коллекций.
Это класс 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();
}
}
Других решений пока нет …