存储复杂数据

时间:2014-12-20 05:11:46

标签: php doctrine-orm

我正在尝试在我的数据库中存储具有各种结构的一些数据。我尝试这样做的方法是创建一个记录实体,并将条目(属性)附加到该记录的条件/值。

Record 1
-> Entity 1 = title:Fruit, dataString:Apple
-> Entity 2 = title:quantity, dataNumber:5
-> Entity 3 = title:color, dataString:red
etc...

Record 2
-> Entity 1 = title:Fruit, dataString:Apple
-> Entity 2 = title:quantity, dataNumber:5
-> Entity 3 = title:color, dataString:green
etc...

我希望能够返回所有颜色结果,其中Fruit == Apple quantity == 5。因此[红色,绿色]

我无法为每种类型的记录创建一个表格,因为我的数据非常复杂,并且每个记录都有不同的属性(条目)

<?php

    namespace App\ReferenceBundle\Entity;

    use Doctrine\ORM\Mapping as ORM;

    /**
     * Entry
     *
     * @ORM\Table()
     * @ORM\Entity(repositoryClass="App\ReferenceBundle\Entity\EntryRepository")
     */
    class Entry
    {
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;

        /**
         * @var string
         *
         * @ORM\Column(name="title", type="string", length=255)
         */
        private $title;

        /**
         * @var string
         *
         * @ORM\Column(name="data_string", type="string", length=255, nullable=true)
         */
        private $dataString;

        /**
         * @var float
         *
         * @ORM\Column(name="data_number", type="float", nullable=true)
         */
        private $dataNumber;


        /**
         * @var App\ReferenceBundle\Entity\Record[]
         *
         * @ORM\ManyToMany(targetEntity="App\ReferenceBundle\Entity\Record", mappedBy="entries")
         */
        private $records;

        /**
         * Get id
         *
         * @return integer 
         */
        public function getId()
        {
            return $this->id;
        }

        /**
         * Set title
         *
         * @param string $title
         * @return Record
         */
        public function setTitle($title)
        {
            $this->title = $title;

            return $this;
        }

        /**
         * Get title
         *
         * @return string 
         */
        public function getTitle()
        {
            return $this->title;
        }

        /**
         * Set dataString
         *
         * @param string $dataString
         * @return Record
         */
        public function setDataString($dataString)
        {
            $this->dataString = $dataString;

            return $this;
        }

        /**
         * Get dataString
         *
         * @return string 
         */
        public function getDataString()
        {
            return $this->dataString;
        }

        /**
         * Set dataNumber
         *
         * @param float $dataNumber
         * @return Record
         */
        public function setDataNumber($dataNumber)
        {
            $this->dataNumber = $dataNumber;

            return $this;
        }

        /**
         * Get dataNumber
         *
         * @return float 
         */
        public function getDataNumber()
        {
            return $this->dataNumber;
        }

        /**
         * Constructor
         */
        public function __construct()
        {
            $this->records = new \Doctrine\Common\Collections\ArrayCollection();
        }

        /**
         * Add records
         *
         * @param \App\ReferenceBundle\Entity\Record $records
         * @return Entry
         */
        public function addRecord(\App\ReferenceBundle\Entity\Record $records)
        {
            $this->records[] = $records;

            return $this;
        }

        /**
         * Remove records
         *
         * @param \App\ReferenceBundle\Entity\Record $records
         */
        public function removeRecord(\App\ReferenceBundle\Entity\Record $records)
        {
            $this->records->removeElement($records);
        }

        /**
         * Get records
         *
         * @return \Doctrine\Common\Collections\Collection 
         */
        public function getRecords()
        {
            return $this->records;
        }
    }


<?php

namespace App\ReferenceBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Record
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="App\ReferenceBundle\Entity\RecordRepository")
 */
class Record
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /** 
     * @var App\ReferenceBundle\Entity\Entry[]
     *
     * @ORM\ManyToMany(targetEntity="App\ReferenceBundle\Entity\Entry", inversedBy="records")
     * @ORM\JoinTable(name="link_records_entries",
     *      joinColumns={@ORM\JoinColumn(name="record_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="entry_id", referencedColumnName="id")}
     *      )
     */
    private $entries;


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->entries = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add entries
     *
     * @param \App\ReferenceBundle\Entity\Entry $entries
     * @return Record
     */
    public function addEntry(\App\ReferenceBundle\Entity\Entry $entries)
    {
        $this->entries[] = $entries;

        return $this;
    }

    /**
     * Remove entries
     *
     * @param \App\ReferenceBundle\Entity\Entry $entries
     */
    public function removeEntry(\App\ReferenceBundle\Entity\Entry $entries)
    {
        $this->entries->removeElement($entries);
    }

    /**
     * Get entries
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getEntries()
    {
        return $this->entries;
    }
}


public function options($matches, $output)
{
    $qb = $this->createQueryBuilder('entry'); 
    $qb->innerJoin('entry.records', 'record'); 
    $qb->innerJoin('record.entries', 'entries'); 



    $qb->where('entry.title = :output');
    $params = ["output" => $output];

    foreach ($matches as $title => $value) { 

        $title1 = str_replace(" ", "_", $title);

        $qb->andWhere('entries.title = :'.$title1.' AND (entries.dataString = :'.$title.'dataString OR entries.dataNumber = :'.$title.'dataNumber)'); 
        $params[$title1] = $title;
        $params[$title."dataString"] = $value;
        $params[$title."dataNumber"] = $value;
    } 

    $qb->setParameters($params);

    $array = $qb 
        ->select('entry.dataString, entry.dataNumber')  
        ->distinct()
        ->getQuery()
        ->getResult();


var_dump($array);exit();

在上面的代码中,$ output将是color,$ matches将包含数量和水果。

显然上面的代码不起作用,因为它试图找到一个包含类型和水果的条目,这是不可能的。我需要返回具有与我的匹配数组匹配的兄弟条目的条目。

我可能不会以正确的方式解决这个问题。任何建议将不胜感激。

2 个答案:

答案 0 :(得分:1)

您需要使用EAV结构(实体,属性,值) - 该结构用于Magento和Drupal。祝你好运!:)

答案 1 :(得分:0)

On下面似乎可以解决这个问题

public function options($matches, $output)
{
    $qb = $this->createQueryBuilder('record'); 



    $qb->innerJoin('record.entries', 'entry'); 

    $qb->where('entry.title = :output');
    $params = ["output" => $output];



    foreach ($matches as $title => $value) { 

        $title1 = str_replace(" ", "_", $title)."match";

        $qb->innerJoin('record.entries', $title1.'entries'); 

        $qb->andWhere($title1.'entries.title = :'.$title1   .' AND ('.$title1.'entries.dataString = :'.$title1.'dataString OR '.$title1.'entries.dataNumber = :'.$title1.'dataNumber)'); 

        $params[$title1] = $title;
        $params[$title1."dataString"] = $value;
        $params[$title1."dataNumber"] = $value;
    }


    $qb->setParameters($params);

    $array = $qb  
        //->select('entry1.title, entry1.dataString, entry1.dataNumber, entry.title as title1')
        ->select('entry.dataString, entry.dataNumber')
        ->distinct()
        ->getQuery()
        ->getResult();


    $arrayFlat = iterator_to_array(new \RecursiveIteratorIterator(new \RecursiveArrayIterator($array)),false);

    $arrayNotNulls = array_filter($arrayFlat, 'strlen');
    $arrayKeysFixed = array_values($arrayNotNulls);

    return $arrayKeysFixed;
}