历史
以以前的方法重建mongo结构以解决内存问题,前一种方法是按区域存储产品,并且所有值都是数组哈希(需要很长时间才能更新)。
当前问题
我似乎无法获取包含键“ x”和值“ y”的引用属性的产品。
聚合\生成器
这种方法只会给我局部值(一个产品可以在30个语言环境中包含5000个值),它的工作原理比Value文档中getValues()上的repositoryMethod更快。
/**
* @param Builder $builder
* @param ExportFilters $exportFilters
*/
private function applyLocaleFilter(Builder &$builder, ExportFilters $exportFilters)
{
if (!$exportFilters->hasLocales()) {
return;
}
// reflectionClass lists properties (still want the name,created,etc with the results).
$fields = MongoProduct::getFieldNames();
// remove "values" key or else i get 5000 results instead of my filtered 90 results
$fields = array_diff($fields, ['values']);
$exp = $builder->expr()->eq('$$value.locale', $exportFilters->getLocale());
$builder
->project()
->includeFields($fields)
->field('values')
->filter('$values', 'value', $exp);
}
例如,我想使用相同的方法通过检查值和引用的属性来继续过滤值;
我希望所有与以下语句匹配的产品(语言环境的值:“ en_GB”)
值的引用属性应为(screen_size),且值必须为“ 16英寸”
它将返回所有与属性过滤与本地化值匹配的产品
Mongo属性
<?php
namespace \MongoBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations\Index;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* Class MongoAttribute
* @package \MongoBundle\Document
*
* @MongoDB\Document(
* repositoryClass="\MongoBundle\Document\Repository\MongoAttributeRepository",
* indexes={@Index(keys={"code"="desc", "name"="desc"}, options={"unique"=true})}
* )
*/
class MongoAttribute
{
/**
* @var int
* @MongoDB\Id(strategy="NONE")
*/
private $id;
/**
* @var string
* @MongoDB\Field(type="string")
*/
private $code;
/**
* @var string
* @MongoDB\Field(type="string")
*/
private $name;
/**
* @var string
* @MongoDB\Field(type="string")
*/
private $type;
/**
* @var string
* @MongoDB\Field(type="string")
*/
private $pre_fix;
/**
* @var string
* @MongoDB\Field(type="string")
*/
private $post_fix;
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @param int $id
* @return $this
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* @return string
*/
public function getCode()
{
return $this->code;
}
/**
* @param string $code
* @return $this
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string $name
* @return $this
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* @param string $type
* @return $this
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* @param string $preFix
* @return $this
*/
public function setPreFix($preFix)
{
$this->pre_fix = $preFix;
return $this;
}
/**
* @return string
*/
public function getPostFix()
{
return $this->post_fix;
}
/**
* @param string $postFix
* @return $this
*/
public function setPostFix($postFix)
{
$this->post_fix = $postFix;
return $this;
}
}
Mongo值
<?php
namespace \MongoBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations\Index;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* Class MongoValue
* @package \MongoBundle\Document
*
* @MongoDB\Document(repositoryClass="\MongoBundle\Document\Repository\MongoValueRepository",
* indexes={@Index(keys={"locale"="desc", "attribute"="desc", "id"="desc"}, options={"unique"=true})}
* )
*/
class MongoValue
{
/**
* @var int
* @MongoDB\Id(strategy="NONE")
*/
private $id;
/**
* @var string
* @MongoDB\Field(type="string")
*/
private $locale;
/**
* @var string
* @MongoDB\Field(type="string")
*/
private $value;
/**
* @var MongoAttribute
* @MongoDB\ReferenceOne(targetDocument="MongoAttribute", cascade={"persist"})
*/
private $attribute;
/**
* @var MongoProduct
* @MongoDB\ReferenceOne(targetDocument="MongoProduct", cascade={"persist"})
*/
private $product;
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @param int $id
* @return $this
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* @return MongoAttribute
*/
public function getAttribute()
{
return $this->attribute;
}
/**
* @param MongoAttribute $attribute
* @return $this
*/
public function setAttribute(MongoAttribute $attribute)
{
$this->attribute = $attribute;
return $this;
}
/**
* @return string
*/
public function getLocale()
{
return $this->locale;
}
/**
* @param string $locale
* @return $this
*/
public function setLocale($locale)
{
$this->locale = $locale;
return $this;
}
/**
* @return string
*/
public function getValue()
{
return $this->value;
}
/**
* @param string $value
* @return $this
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* @return MongoProduct
*/
public function getProduct()
{
return $this->product;
}
/**
* @param MongoProduct $product
* @return $this
*/
public function setProduct(MongoProduct $product)
{
$this->product = $product;
return $this;
}
}
Mongo产品
<?php
namespace \MongoBundle\Document;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Doctrine\ODM\MongoDB\Mapping\Annotations\Index;
use ReflectionClass;
use \CatalogBundle\Entity\Locale;
/**
* Class MongoProduct
* @package \MongoBundle\Document
*
* @MongoDB\Document(repositoryClass="\MongoBundle\Document\Repository\MongoProductRepository",
* indexes={@Index(keys={"id"="desc", "name"="desc"}, options={"unique"=true})}
* )
*/
class MongoProduct
{
/**
* @var integer
* @MongoDB\Id(strategy="NONE")
*/
protected $id;
/**
* @var string
* @MongoDB\Field(type="string")
*/
protected $name;
/**
* @var \DateTime
* @MongoDB\Field(type="date")
*/
protected $created;
/**
* @var \DateTime
* @MongoDB\Field(type="date")
*/
protected $updated;
/**
* @var boolean
* @MongoDB\Field(type="bool")
*/
protected $archived;
/**
* @var integer
* @MongoDB\Field(type="bool")
*/
protected $is_parent;
/**
* @var integer
* @MongoDB\Field(type="bool")
*/
protected $is_child;
/**
* @var boolean
* @MongoDB\Field(type="bool")
*/
protected $is_single;
/**
* @var string
* @MongoDB\Field(type="string")
*/
protected $attribute_set_id;
/**
* @var string
* @MongoDB\Field(type="string")
*/
protected $attribute_set_name;
/**
* @var MongoProduct
* @MongoDB\ReferenceOne(targetDocument="MongoProduct")
*/
protected $parent;
/**
* @var MongoProduct[]
* @MongoDB\ReferenceMany(targetDocument="MongoProduct", cascade={"persist"}, orphanRemoval=true)
*/
protected $children;
/**
* @var MongoValue[]
* @MongoDB\ReferenceMany(targetDocument="MongoValue", cascade={"persist"}, orphanRemoval=true)
*/
protected $values;
/**
* MongoProduct constructor.
*/
public function __construct()
{
$this->children = new ArrayCollection();
$this->values = new ArrayCollection();
}
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @param int $id
* @return $this
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string $name
* @return $this
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* @return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* @return \DateTime
*/
public function getUpdated()
{
return $this->updated;
}
/**
* @param \DateTime $updated
* @return $this
*/
public function setUpdated(\DateTime $updated)
{
$this->updated = $updated;
return $this;
}
/**
* @return bool
*/
public function isArchived()
{
return $this->archived;
}
/**
* @param bool $archived
* @return $this
*/
public function setArchived($archived)
{
$this->archived = $archived;
return $this;
}
/**
* @return int
*/
public function getIsParent()
{
return $this->isParent;
}
/**
* @param int $isParent
* @return $this
*/
public function setIsParent($isParent)
{
$this->isParent = $isParent;
return $this;
}
/**
* @return int
*/
public function getIsChild()
{
return $this->is_child;
}
/**
* @param int $isChild
* @return $this
*/
public function setIsChild($isChild)
{
$this->is_child = $isChild;
return $this;
}
/**
* @return bool
*/
public function isSingle()
{
return $this->is_single;
}
/**
* @param bool $isSingle
* @return $this
*/
public function setIsSingle($isSingle)
{
$this->is_single = $isSingle;
return $this;
}
/**
* @return string
*/
public function getAttributeSetId()
{
return $this->attribute_set_id;
}
/**
* @param string $attributeSetId
* @return $this
*/
public function setAttributeSetId($attributeSetId)
{
$this->attribute_set_id = $attributeSetId;
return $this;
}
/**
* @return string
*/
public function getAttributeSetName()
{
return $this->attribute_set_name;
}
/**
* @param string $attributeSetName
* @return $this
*/
public function setAttributeSetName($attributeSetName)
{
$this->attribute_set_name = $attributeSetName;
return $this;
}
/**
* @return MongoProduct
*/
public function getParent()
{
return $this->parent;
}
/**
* @param MongoProduct $parent
* @return $this
*/
public function setParent($parent)
{
$this->parent = $parent;
return $this;
}
/**
* @return MongoProduct[]
*/
public function getChildren()
{
return $this->children;
}
/**
* @param MongoProduct[] $children
* @return $this
*/
public function setChildren($children)
{
$this->children = $children;
return $this;
}
/**
* @param Locale|null $locale
* @return MongoValue[]
*/
public function getValues(Locale $locale = null)
{
$result = new ArrayCollection();
if ($locale instanceof Locale) {
foreach ($this->values as $value) {
if ($locale->getCode() == $value->getLocale()) {
$result->add($value);
}
}
} else {
$result = $this->values;
}
return $result;
}
/**
* @param Locale|null $locale
* @return MongoValue[]
*/
public function getValuesMappedByAttribute(Locale $locale = null)
{
$result = [];
foreach ($this->getValues($locale) as $value) {
$result[$value->getAttribute()->getId()] = $value;
}
return $result;
}
/**
* @param MongoValue[] $values
* @return $this
*/
public function setValues($values)
{
$this->values = $values;
return $this;
}
/**
* @param \DateTime $created
* @return $this
*/
public function setCreated(\DateTime $created)
{
$this->created = $created;
return $this;
}
/**
* @return array
*/
static function getFieldNames()
{
try {
$reflection = new ReflectionClass(MongoProduct::class);
$result = array_column($reflection->getProperties(), 'name');
} catch (\ReflectionException $e) {
$result = [];
}
return $result;
}
}