Objektpersitenz

Für die Suche nach Objekten erlaubt es ein Index schnell auf die gesuchten Objekte zuzugreifen. Die Erstellung des Index für serialisierte Objekte ist allerdings problematisch. Aus diesem Grund arbeiten viele Frameworks beim Speichern von Objekten mit ORM. Hierbei werden Eigenschaften auf Spalten gemappt. Alvine geht hier einen anderen Weg und erlaubt das anlegen von externen Indexen für die Suche. Im wesentlichen beruht das Konzept auf einem Objektspeicher und einer optimierten Suche.

$uri = new \Alvine\Net\Resource\URI('mongodb://127.0.0.1:27017/object/collection');
$provider = new Alvine\Persistence\Provider\MongoDB\DataObject($uri);
$storage = new \Alvine\Persistence\ObjectStorage($provider);

// Manager ist Singlton
$manager = \Alvine\Persistence\Manager::getInstance();
$manager->registerDefaultStorage($storage);

Ablauf einer Indexierung

Ein FindObserver Plugin kann per attachObserver() an ein DataObject gehängt werden. Ändert das DataObject den Wert in der Datenbank wird die update() Methode des findObservers aufgerufen. Dieser wiederum trägt die Änderung in den Index ein.

Zur Vorbereitung muss in der MySQL-Datenbank eine Tabelle angelegt werden.

Für diese Beispiele müssen die entsprechenden Provider-Komponenten (Phar-Archive) geladen werden.

CREATE TABLE IF NOT EXISTS `alvine` ( 
`sys_ID` varchar(255) NOT NULL COMMENT 'ID des Objektes, bei Alvine-Objekten ist dies eine UUID', 
`sys_so` text NOT NULL COMMENT 'Serialisierte Objektdaten',
`sys_creation` datetime NOT NULL COMMENT 'Dieses Objekt wurde zu diesem Zeitpunkt erstellt', 
`sys_lastupdate` datetime NOT NULL COMMENT 'Die letzte änderung am Objekt erfolgte zu dieser Zeit',PRIMARY KEY (`sys_ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Speicher für Alvine-Objekte'

Der Name der Tabelle kann frei gewählt werden und muss mit der URI an den Provider übergeben werden.

Siehe auch Namespace AlvinePersistenceProviderMySQL

Objekt anlegen

Ein soll ein Datenobjekt mittels den Werten SKU oder Artikelname gefunden werden.

/**
 * Indizierbares Produkt
 */
class IndexableItem extends \Alvine\Types\Map\SimpleMap implements Alvine\Persistence\Find\Indexable {

    protected $itemName=null;
    protected $sku=null;
    protected $price=null;

    /**
     * Neues Produkt erstellen
     */
    public function __construct($sku, $itemName, $price) {
        parent::__construct();
        $this->itemName=$itemName;
        $this->sku=$sku;
        $this->price=$price;
    }

    /**
     * Neues IndexDokument mit allen Indexwerten erstellen
     */
    public function getIndexDocument() {
        return (new Alvine\Persistence\Find\IndexDocument('IndexableItem', $this->getID()))->setValue('itemName', $this->itemName)
                ->setValue('sku', $this->sku)
                ->setValue('price', $this->price);
    }

}

/**
 * Objektspeicher zuweisen
 * Hier eine MySQL-Datenbank.
 */
$dataObject=new \Alvine\Persistence\Provider\MySQL\DataObject(new Alvine\Net\Resource\URI('mysql://user:password@localhost/alvine2/test'));
$storage=new \Alvine\Persistence\ObjectStorage($dataObject);

/**
 * Der Indexer sorgt für
 * das Updaate des Index.
 *
 * Über die IndexMap können unterschiedliche
 * Feldnamen gemappt werden.
 */
$indexer=new \Alvine\Persistence\Provider\Solr\IndexObserver(new Alvine\Net\Resource\URI('http://localhost:8983/solr/alvine-objectindex'), (new \Alvine\Persistence\Find\IndexMap())
        ->setValue('itemName', 'string_itemName')
        ->setValue('sku', 'string_sku')
        ->setValue('price', 'string_price'));

/**
 * Index als Beobachter in der Storage-Engine eintragen
 */
$storage->attachObserver($indexer);

/**
 * Objekt erstellen und schreiben
 */
$item=new IndexableItem('1425', 'Baseball Mütze', '14.25');
$storage->writeObject($item);

Im Objektspeicher - in diesem Fall eine MySQL-Datenbank - findet man ein Eintrag mit dem neue Objekt.

Objekt suchen

Will man die gespeicherten Produkte wiederfinden, so bedient man sich des Solr-Index.

Über eine Solr-Abfrage über das Feld sys_id kann man das Objekt aus der Datenbank in Solr leicht finden. Es können auch mittels fq=string_price%3A14.25 alle Produkte mit einem Preis von 14.25 abgerufen werden.

/*
 * Neues Finder Objekt erstellen
 * Übergabe einer SOLR URI
 *
 */
$finder = new \Alvine\Persistence\Provider\Solr\IndexFinder(new Alvine\Net\Resource\URI('http://127.0.0.1:8983/solr/alvine-objectindex'));

/*
 * Die Abfrage an die Datenbank
 * In diesem Beispiel wird der Wert "string_sku" mit dem Wert "1428" gesucht
 *
 */
$result = $finder->find('string_sku:1428');