我在symfony2中有一个带有嵌入式文档的mongodb文档:
/**
* @MongoDBEmbedMany(targetDocument="Restriction")
*/
private $restrictions = array();
public function __construct()
{
$this->restrictions = new DoctrineCommonCollectionsArrayCollection();
}
限制文档有两个属性。 from_pos和长度。我希望这个数组总是按from_pos排序,所以在整个应用程序中,我将始终确保这个列表是排序的。
有没有一种简单的方法可以自动执行此操作?我的意思是,调用addRestriction函数,这将自动保存在按我想要的键排序的mongodb数据库中。
目前,addRestriction函数只是将新文档添加到列表的末尾。
/**
* Add restriction
*
* @param MyBundleDocumentRestriction $restriction
*/
public function addRestriction(MyBundleDocumentRestriction $restriction)
{
$this->restrictions[] = $restriction;
}
我可以更新此功能以将限制插入所需的位置,但我想知道是否有最简单的方法。
解决方案是使用自定义集合。
http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/custom-collections.html
这是我开发的 SortedCollection 类。添加元素时,只需将其放在正确的位置并切片其他元素即可。
<?php
use DoctrineCommonCollectionsArrayCollection;
/**
* 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
{
/**
* @MongoDBEmbedMany(
* collectionClass="SortedCollection",
* targetDocument="...."
* )
*/
private $sorted_list = array();
public function __construct()
{
$this->sorted_list = new SortedCollection();
}
}