Query by reference in Doctrine ODM (Mongo)
up vote
0
down vote
favorite
History
Recreating mongo structure to combat memory issues in the former approach where a product is stored per locale and all values are an array hash (took to long to update).
Current problem
I can't seem to fetch products containing a referenced attribute with key "x" and value "y".
AggregationBuilder
This approach will give me only localized values (a product can contain 5000 values for 30 locales), it works and it is faster than a repositoryMethod on the getValues() in the Value document.
/**
* @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);
}
I wanted to use the same approach to continue to filter the values by checking their value and referenced attribute, for example;
I want all products (with values for locale: "en_GB") that matches with the statement below
referenced attribute for a value should be (screen_size) and must have value "16 inches"
it will return all products that match the attribute filtering with the localized values
Mongo Attribute
<?php
namespace MongoBundleDocument;
use DoctrineODMMongoDBMappingAnnotationsIndex;
use DoctrineODMMongoDBMappingAnnotations as MongoDB;
/**
* Class MongoAttribute
* @package MongoBundleDocument
*
* @MongoDBDocument(
* repositoryClass="MongoBundleDocumentRepositoryMongoAttributeRepository",
* indexes={@Index(keys={"code"="desc", "name"="desc"}, options={"unique"=true})}
* )
*/
class MongoAttribute
{
/**
* @var int
* @MongoDBId(strategy="NONE")
*/
private $id;
/**
* @var string
* @MongoDBField(type="string")
*/
private $code;
/**
* @var string
* @MongoDBField(type="string")
*/
private $name;
/**
* @var string
* @MongoDBField(type="string")
*/
private $type;
/**
* @var string
* @MongoDBField(type="string")
*/
private $pre_fix;
/**
* @var string
* @MongoDBField(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 Value
<?php
namespace MongoBundleDocument;
use DoctrineODMMongoDBMappingAnnotationsIndex;
use DoctrineODMMongoDBMappingAnnotations as MongoDB;
/**
* Class MongoValue
* @package MongoBundleDocument
*
* @MongoDBDocument(repositoryClass="MongoBundleDocumentRepositoryMongoValueRepository",
* indexes={@Index(keys={"locale"="desc", "attribute"="desc", "id"="desc"}, options={"unique"=true})}
* )
*/
class MongoValue
{
/**
* @var int
* @MongoDBId(strategy="NONE")
*/
private $id;
/**
* @var string
* @MongoDBField(type="string")
*/
private $locale;
/**
* @var string
* @MongoDBField(type="string")
*/
private $value;
/**
* @var MongoAttribute
* @MongoDBReferenceOne(targetDocument="MongoAttribute", cascade={"persist"})
*/
private $attribute;
/**
* @var MongoProduct
* @MongoDBReferenceOne(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 Product
<?php
namespace MongoBundleDocument;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineODMMongoDBMappingAnnotations as MongoDB;
use DoctrineODMMongoDBMappingAnnotationsIndex;
use ReflectionClass;
use CatalogBundleEntityLocale;
/**
* Class MongoProduct
* @package MongoBundleDocument
*
* @MongoDBDocument(repositoryClass="MongoBundleDocumentRepositoryMongoProductRepository",
* indexes={@Index(keys={"id"="desc", "name"="desc"}, options={"unique"=true})}
* )
*/
class MongoProduct
{
/**
* @var integer
* @MongoDBId(strategy="NONE")
*/
protected $id;
/**
* @var string
* @MongoDBField(type="string")
*/
protected $name;
/**
* @var DateTime
* @MongoDBField(type="date")
*/
protected $created;
/**
* @var DateTime
* @MongoDBField(type="date")
*/
protected $updated;
/**
* @var boolean
* @MongoDBField(type="bool")
*/
protected $archived;
/**
* @var integer
* @MongoDBField(type="bool")
*/
protected $is_parent;
/**
* @var integer
* @MongoDBField(type="bool")
*/
protected $is_child;
/**
* @var boolean
* @MongoDBField(type="bool")
*/
protected $is_single;
/**
* @var string
* @MongoDBField(type="string")
*/
protected $attribute_set_id;
/**
* @var string
* @MongoDBField(type="string")
*/
protected $attribute_set_name;
/**
* @var MongoProduct
* @MongoDBReferenceOne(targetDocument="MongoProduct")
*/
protected $parent;
/**
* @var MongoProduct
* @MongoDBReferenceMany(targetDocument="MongoProduct", cascade={"persist"}, orphanRemoval=true)
*/
protected $children;
/**
* @var MongoValue
* @MongoDBReferenceMany(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;
}
}
mongodb doctrine odm
add a comment |
up vote
0
down vote
favorite
History
Recreating mongo structure to combat memory issues in the former approach where a product is stored per locale and all values are an array hash (took to long to update).
Current problem
I can't seem to fetch products containing a referenced attribute with key "x" and value "y".
AggregationBuilder
This approach will give me only localized values (a product can contain 5000 values for 30 locales), it works and it is faster than a repositoryMethod on the getValues() in the Value document.
/**
* @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);
}
I wanted to use the same approach to continue to filter the values by checking their value and referenced attribute, for example;
I want all products (with values for locale: "en_GB") that matches with the statement below
referenced attribute for a value should be (screen_size) and must have value "16 inches"
it will return all products that match the attribute filtering with the localized values
Mongo Attribute
<?php
namespace MongoBundleDocument;
use DoctrineODMMongoDBMappingAnnotationsIndex;
use DoctrineODMMongoDBMappingAnnotations as MongoDB;
/**
* Class MongoAttribute
* @package MongoBundleDocument
*
* @MongoDBDocument(
* repositoryClass="MongoBundleDocumentRepositoryMongoAttributeRepository",
* indexes={@Index(keys={"code"="desc", "name"="desc"}, options={"unique"=true})}
* )
*/
class MongoAttribute
{
/**
* @var int
* @MongoDBId(strategy="NONE")
*/
private $id;
/**
* @var string
* @MongoDBField(type="string")
*/
private $code;
/**
* @var string
* @MongoDBField(type="string")
*/
private $name;
/**
* @var string
* @MongoDBField(type="string")
*/
private $type;
/**
* @var string
* @MongoDBField(type="string")
*/
private $pre_fix;
/**
* @var string
* @MongoDBField(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 Value
<?php
namespace MongoBundleDocument;
use DoctrineODMMongoDBMappingAnnotationsIndex;
use DoctrineODMMongoDBMappingAnnotations as MongoDB;
/**
* Class MongoValue
* @package MongoBundleDocument
*
* @MongoDBDocument(repositoryClass="MongoBundleDocumentRepositoryMongoValueRepository",
* indexes={@Index(keys={"locale"="desc", "attribute"="desc", "id"="desc"}, options={"unique"=true})}
* )
*/
class MongoValue
{
/**
* @var int
* @MongoDBId(strategy="NONE")
*/
private $id;
/**
* @var string
* @MongoDBField(type="string")
*/
private $locale;
/**
* @var string
* @MongoDBField(type="string")
*/
private $value;
/**
* @var MongoAttribute
* @MongoDBReferenceOne(targetDocument="MongoAttribute", cascade={"persist"})
*/
private $attribute;
/**
* @var MongoProduct
* @MongoDBReferenceOne(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 Product
<?php
namespace MongoBundleDocument;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineODMMongoDBMappingAnnotations as MongoDB;
use DoctrineODMMongoDBMappingAnnotationsIndex;
use ReflectionClass;
use CatalogBundleEntityLocale;
/**
* Class MongoProduct
* @package MongoBundleDocument
*
* @MongoDBDocument(repositoryClass="MongoBundleDocumentRepositoryMongoProductRepository",
* indexes={@Index(keys={"id"="desc", "name"="desc"}, options={"unique"=true})}
* )
*/
class MongoProduct
{
/**
* @var integer
* @MongoDBId(strategy="NONE")
*/
protected $id;
/**
* @var string
* @MongoDBField(type="string")
*/
protected $name;
/**
* @var DateTime
* @MongoDBField(type="date")
*/
protected $created;
/**
* @var DateTime
* @MongoDBField(type="date")
*/
protected $updated;
/**
* @var boolean
* @MongoDBField(type="bool")
*/
protected $archived;
/**
* @var integer
* @MongoDBField(type="bool")
*/
protected $is_parent;
/**
* @var integer
* @MongoDBField(type="bool")
*/
protected $is_child;
/**
* @var boolean
* @MongoDBField(type="bool")
*/
protected $is_single;
/**
* @var string
* @MongoDBField(type="string")
*/
protected $attribute_set_id;
/**
* @var string
* @MongoDBField(type="string")
*/
protected $attribute_set_name;
/**
* @var MongoProduct
* @MongoDBReferenceOne(targetDocument="MongoProduct")
*/
protected $parent;
/**
* @var MongoProduct
* @MongoDBReferenceMany(targetDocument="MongoProduct", cascade={"persist"}, orphanRemoval=true)
*/
protected $children;
/**
* @var MongoValue
* @MongoDBReferenceMany(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;
}
}
mongodb doctrine odm
It's hard to say what you're trying to achieve/what is going wrong with info provided. Also there's a lot of noise not connected with the question at hand (i.e. half ofMongoProduct
, accessors in other classes). Anyways, try playing with aggregation builder in console and "translate" it to ODM after you have working pipeline, it'll be easier that way.
– malarzm
12 hours ago
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
History
Recreating mongo structure to combat memory issues in the former approach where a product is stored per locale and all values are an array hash (took to long to update).
Current problem
I can't seem to fetch products containing a referenced attribute with key "x" and value "y".
AggregationBuilder
This approach will give me only localized values (a product can contain 5000 values for 30 locales), it works and it is faster than a repositoryMethod on the getValues() in the Value document.
/**
* @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);
}
I wanted to use the same approach to continue to filter the values by checking their value and referenced attribute, for example;
I want all products (with values for locale: "en_GB") that matches with the statement below
referenced attribute for a value should be (screen_size) and must have value "16 inches"
it will return all products that match the attribute filtering with the localized values
Mongo Attribute
<?php
namespace MongoBundleDocument;
use DoctrineODMMongoDBMappingAnnotationsIndex;
use DoctrineODMMongoDBMappingAnnotations as MongoDB;
/**
* Class MongoAttribute
* @package MongoBundleDocument
*
* @MongoDBDocument(
* repositoryClass="MongoBundleDocumentRepositoryMongoAttributeRepository",
* indexes={@Index(keys={"code"="desc", "name"="desc"}, options={"unique"=true})}
* )
*/
class MongoAttribute
{
/**
* @var int
* @MongoDBId(strategy="NONE")
*/
private $id;
/**
* @var string
* @MongoDBField(type="string")
*/
private $code;
/**
* @var string
* @MongoDBField(type="string")
*/
private $name;
/**
* @var string
* @MongoDBField(type="string")
*/
private $type;
/**
* @var string
* @MongoDBField(type="string")
*/
private $pre_fix;
/**
* @var string
* @MongoDBField(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 Value
<?php
namespace MongoBundleDocument;
use DoctrineODMMongoDBMappingAnnotationsIndex;
use DoctrineODMMongoDBMappingAnnotations as MongoDB;
/**
* Class MongoValue
* @package MongoBundleDocument
*
* @MongoDBDocument(repositoryClass="MongoBundleDocumentRepositoryMongoValueRepository",
* indexes={@Index(keys={"locale"="desc", "attribute"="desc", "id"="desc"}, options={"unique"=true})}
* )
*/
class MongoValue
{
/**
* @var int
* @MongoDBId(strategy="NONE")
*/
private $id;
/**
* @var string
* @MongoDBField(type="string")
*/
private $locale;
/**
* @var string
* @MongoDBField(type="string")
*/
private $value;
/**
* @var MongoAttribute
* @MongoDBReferenceOne(targetDocument="MongoAttribute", cascade={"persist"})
*/
private $attribute;
/**
* @var MongoProduct
* @MongoDBReferenceOne(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 Product
<?php
namespace MongoBundleDocument;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineODMMongoDBMappingAnnotations as MongoDB;
use DoctrineODMMongoDBMappingAnnotationsIndex;
use ReflectionClass;
use CatalogBundleEntityLocale;
/**
* Class MongoProduct
* @package MongoBundleDocument
*
* @MongoDBDocument(repositoryClass="MongoBundleDocumentRepositoryMongoProductRepository",
* indexes={@Index(keys={"id"="desc", "name"="desc"}, options={"unique"=true})}
* )
*/
class MongoProduct
{
/**
* @var integer
* @MongoDBId(strategy="NONE")
*/
protected $id;
/**
* @var string
* @MongoDBField(type="string")
*/
protected $name;
/**
* @var DateTime
* @MongoDBField(type="date")
*/
protected $created;
/**
* @var DateTime
* @MongoDBField(type="date")
*/
protected $updated;
/**
* @var boolean
* @MongoDBField(type="bool")
*/
protected $archived;
/**
* @var integer
* @MongoDBField(type="bool")
*/
protected $is_parent;
/**
* @var integer
* @MongoDBField(type="bool")
*/
protected $is_child;
/**
* @var boolean
* @MongoDBField(type="bool")
*/
protected $is_single;
/**
* @var string
* @MongoDBField(type="string")
*/
protected $attribute_set_id;
/**
* @var string
* @MongoDBField(type="string")
*/
protected $attribute_set_name;
/**
* @var MongoProduct
* @MongoDBReferenceOne(targetDocument="MongoProduct")
*/
protected $parent;
/**
* @var MongoProduct
* @MongoDBReferenceMany(targetDocument="MongoProduct", cascade={"persist"}, orphanRemoval=true)
*/
protected $children;
/**
* @var MongoValue
* @MongoDBReferenceMany(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;
}
}
mongodb doctrine odm
History
Recreating mongo structure to combat memory issues in the former approach where a product is stored per locale and all values are an array hash (took to long to update).
Current problem
I can't seem to fetch products containing a referenced attribute with key "x" and value "y".
AggregationBuilder
This approach will give me only localized values (a product can contain 5000 values for 30 locales), it works and it is faster than a repositoryMethod on the getValues() in the Value document.
/**
* @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);
}
I wanted to use the same approach to continue to filter the values by checking their value and referenced attribute, for example;
I want all products (with values for locale: "en_GB") that matches with the statement below
referenced attribute for a value should be (screen_size) and must have value "16 inches"
it will return all products that match the attribute filtering with the localized values
Mongo Attribute
<?php
namespace MongoBundleDocument;
use DoctrineODMMongoDBMappingAnnotationsIndex;
use DoctrineODMMongoDBMappingAnnotations as MongoDB;
/**
* Class MongoAttribute
* @package MongoBundleDocument
*
* @MongoDBDocument(
* repositoryClass="MongoBundleDocumentRepositoryMongoAttributeRepository",
* indexes={@Index(keys={"code"="desc", "name"="desc"}, options={"unique"=true})}
* )
*/
class MongoAttribute
{
/**
* @var int
* @MongoDBId(strategy="NONE")
*/
private $id;
/**
* @var string
* @MongoDBField(type="string")
*/
private $code;
/**
* @var string
* @MongoDBField(type="string")
*/
private $name;
/**
* @var string
* @MongoDBField(type="string")
*/
private $type;
/**
* @var string
* @MongoDBField(type="string")
*/
private $pre_fix;
/**
* @var string
* @MongoDBField(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 Value
<?php
namespace MongoBundleDocument;
use DoctrineODMMongoDBMappingAnnotationsIndex;
use DoctrineODMMongoDBMappingAnnotations as MongoDB;
/**
* Class MongoValue
* @package MongoBundleDocument
*
* @MongoDBDocument(repositoryClass="MongoBundleDocumentRepositoryMongoValueRepository",
* indexes={@Index(keys={"locale"="desc", "attribute"="desc", "id"="desc"}, options={"unique"=true})}
* )
*/
class MongoValue
{
/**
* @var int
* @MongoDBId(strategy="NONE")
*/
private $id;
/**
* @var string
* @MongoDBField(type="string")
*/
private $locale;
/**
* @var string
* @MongoDBField(type="string")
*/
private $value;
/**
* @var MongoAttribute
* @MongoDBReferenceOne(targetDocument="MongoAttribute", cascade={"persist"})
*/
private $attribute;
/**
* @var MongoProduct
* @MongoDBReferenceOne(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 Product
<?php
namespace MongoBundleDocument;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineODMMongoDBMappingAnnotations as MongoDB;
use DoctrineODMMongoDBMappingAnnotationsIndex;
use ReflectionClass;
use CatalogBundleEntityLocale;
/**
* Class MongoProduct
* @package MongoBundleDocument
*
* @MongoDBDocument(repositoryClass="MongoBundleDocumentRepositoryMongoProductRepository",
* indexes={@Index(keys={"id"="desc", "name"="desc"}, options={"unique"=true})}
* )
*/
class MongoProduct
{
/**
* @var integer
* @MongoDBId(strategy="NONE")
*/
protected $id;
/**
* @var string
* @MongoDBField(type="string")
*/
protected $name;
/**
* @var DateTime
* @MongoDBField(type="date")
*/
protected $created;
/**
* @var DateTime
* @MongoDBField(type="date")
*/
protected $updated;
/**
* @var boolean
* @MongoDBField(type="bool")
*/
protected $archived;
/**
* @var integer
* @MongoDBField(type="bool")
*/
protected $is_parent;
/**
* @var integer
* @MongoDBField(type="bool")
*/
protected $is_child;
/**
* @var boolean
* @MongoDBField(type="bool")
*/
protected $is_single;
/**
* @var string
* @MongoDBField(type="string")
*/
protected $attribute_set_id;
/**
* @var string
* @MongoDBField(type="string")
*/
protected $attribute_set_name;
/**
* @var MongoProduct
* @MongoDBReferenceOne(targetDocument="MongoProduct")
*/
protected $parent;
/**
* @var MongoProduct
* @MongoDBReferenceMany(targetDocument="MongoProduct", cascade={"persist"}, orphanRemoval=true)
*/
protected $children;
/**
* @var MongoValue
* @MongoDBReferenceMany(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;
}
}
mongodb doctrine odm
mongodb doctrine odm
edited 18 hours ago
asked 20 hours ago
SinisterGlitch
30218
30218
It's hard to say what you're trying to achieve/what is going wrong with info provided. Also there's a lot of noise not connected with the question at hand (i.e. half ofMongoProduct
, accessors in other classes). Anyways, try playing with aggregation builder in console and "translate" it to ODM after you have working pipeline, it'll be easier that way.
– malarzm
12 hours ago
add a comment |
It's hard to say what you're trying to achieve/what is going wrong with info provided. Also there's a lot of noise not connected with the question at hand (i.e. half ofMongoProduct
, accessors in other classes). Anyways, try playing with aggregation builder in console and "translate" it to ODM after you have working pipeline, it'll be easier that way.
– malarzm
12 hours ago
It's hard to say what you're trying to achieve/what is going wrong with info provided. Also there's a lot of noise not connected with the question at hand (i.e. half of
MongoProduct
, accessors in other classes). Anyways, try playing with aggregation builder in console and "translate" it to ODM after you have working pipeline, it'll be easier that way.– malarzm
12 hours ago
It's hard to say what you're trying to achieve/what is going wrong with info provided. Also there's a lot of noise not connected with the question at hand (i.e. half of
MongoProduct
, accessors in other classes). Anyways, try playing with aggregation builder in console and "translate" it to ODM after you have working pipeline, it'll be easier that way.– malarzm
12 hours ago
add a comment |
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53372060%2fquery-by-reference-in-doctrine-odm-mongo%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
It's hard to say what you're trying to achieve/what is going wrong with info provided. Also there's a lot of noise not connected with the question at hand (i.e. half of
MongoProduct
, accessors in other classes). Anyways, try playing with aggregation builder in console and "translate" it to ODM after you have working pipeline, it'll be easier that way.– malarzm
12 hours ago