Sie sind nicht angemeldet.

Lieber Besucher, herzlich willkommen bei: Booking Monitor Supportforum. Falls dies Ihr erster Besuch auf dieser Seite ist, lesen Sie sich bitte die Hilfe durch. Dort wird Ihnen die Bedienung dieser Seite näher erläutert. Darüber hinaus sollten Sie sich registrieren, um alle Funktionen dieser Seite nutzen zu können. Benutzen Sie das Registrierungsformular, um sich zu registrieren oder informieren Sie sich ausführlich über den Registrierungsvorgang. Falls Sie sich bereits zu einem früheren Zeitpunkt registriert haben, können Sie sich hier anmelden.

Alexander

Schüler

  • »Alexander« ist der Autor dieses Themas

Beiträge: 143

Wohnort: Obersulm

Beruf: Programmierer

  • Nachricht senden

1

18.06.2010, 14:51

[Aus dem Blog 19.04.2009] Suche nach freien Objekten – eine Wissenschaft

Es ist erstaunlich, wie schwierig es war die Suche zu implementieren. Das System verfügt dank der Flexibilität über so viele Kriterien, dass allein die Suchklasse ca. 1.000 Zeilen Code beinhaltet. Ganz zu schweigen von unzähligen Controller-, DB-Schichten und weiteren Unterstützungsfunktionen in anderen Klassen.

Um sich einen Überblick über die Klasse zu verschaffen, kann man sich die Daten unter folgendem Link ansehen (Link). Wie die Suche funktioniert, kann man im Backend sehen. Damit der Kunde die Suche eigenen Gästen zur Verfügung stellen kann, befindet sich der Suchcontroller in dem SME Modul. Dort habe ich 2 Demoseiten erstellt. Die eine Demoseite ist für die einfache Suche und die andere Demoseite für die erweiterte Suche angelegt:
Codeblöcke, die der Kunde in die eigene Seite einbauen soll, sind im HTML-Quelltext mit Kommentaren hervorgehoben. Das sind ein paar Javascript Dateien mit Initialisierungen und ein paar Elemente mit entsprechenden ID’s, die als Container für die Inhalte dienen.

Nachdem eine SME-Seite geladen ist, prüft Javascript ob Elemente mit notwendigen ID’s im Quelltext vorhanden sind. Wenn ja, wird eine AJAX-Anfrage ausgelöst, die die Formulare für die Suche lädt und in die Seite (div) einfügt. Sobald der Gast dann die Kriterien für die Suche eingegeben hat und auf den Such-Button klickt, wird eine erneute AJAX-Anfrage gesendet. Diesmal an die “search” Aktion des “search” Controllers im SME-Modul. Der Controller erstellt eine neue Instanz der Search-Model-Klasse, führt ein paar Initialisierungen durch und ruft anschließend die “search” Methode der Modelklasse auf.

Die Methode “search” der Suchklasse erledigt die ganze “schmutzige” Arbeit und gibt an den Controller Informationen zurück, anhand deren der Controller dann eine Antwort an den Client zusammensetzen kann.

Den Code komplett und detailliert zu beschreiben wäre an dieser Stelle natürlich nicht besonderes hilfreich, deswegen beschränke ich mich nur auf die wichtigsten Aspekte der Suche. Derzeit wird die Suche noch an den Livedaten ausgeführt, was die Suchfunktion nicht gerade zu einem flixen Renner macht. Das gilt insbesondere dann, wenn man über einen großen Zeitraum (ab 3 Monate) und nach einer kurzen Mietperiode (bis 5-7 Tage) sucht. Deswegen habe ich eine neue Limitierung eingeführt, die die Suche über größere Perioden verbietet. Diese Limitierung habe ich auf 60 Tage eingestellt und sie kann unter Einstellungen im Backend vom Administrator jederzeit verändert werden.

Um die Suche zukünftig schneller zu machen, plane ich später eine de-normalisierte und redundante Tabelle einzuführen, die der Administrator nach Pflegeabschluss neu generieren bzw. updaten kann. Ohne diese Tabelle ist die Suche kaum zu beschleunigen.

Ich möchte an dieser Stelle noch mal anmerken, dass die Suche erst ab dem großen Zeitraum langsamer wird. Suchanfragen innerhalb von Zeiträumen bis 2-3 Monate und für Mietzeiträume ab 3 Tage werden sehr schnell ausgeführt. Seiten, die mehrere Zehntausend Suchabfragen pro Tag zählen, müssen auf die de-normalisierte Tabelle wohl noch warten. Darüber später mehr.

Ein allgemeines internes Problem bei der Suche nach freien Objekten besteht in (wahrscheinlich) jedem Programm. Dies ist so, da eine einzelne Operation nach freien Objekten gar nicht suchen kann, da man ja keine freien Zeiträume speichert. Stattdessen liegen in der Datenbank nur die belegten Zeiträume.

Um das Problem zu umgehen, habe ich bereits im Jahr 2006 eine Ausschlusssuche (exclution search) in meine Programme eingeführt. D.h. man findet alle Objekte, die belegt sind und schließt sie einfach aus. Die Suche nach belegten Objekten sieht folgendermaßen aus:

PHP-Quelltext

1
2
3
4
5
$select $db->select()
    ->from(DBT::BM_BOOKING, array('offer_id''occplan_id''begin''end''id'))
    ->where('begin <= ?'$this->end->get('yyyy-MM-dd'))
    ->where('end <= ?'$this->begin->get('yyyy-MM-dd'))
    ->order('begin');


Damit werden die belegten Objekte, in diesem Fall Angebote und Belegungspläne, gefunden und aus den Suchergebnissen “entfernt”. Damit beschäftigt sich folgender Codeblock:

PHP-Quelltext

1
2
3
4
5
6
7
if ($this->flags self::FULL_DUARION) {
    foreach ($rows as $row) {
        if ($row['begin'] != $this->end->get('yyyy-MM-dd')
                    && $row['end'] != $this->begin->get('yyyy-MM-dd'))
            unset($this->plans[$row['occplan_id']]);
    }
}


Eine weitere Schwierigkeit gibt es, wenn der Gast bzw. jemand anderer nach einer Mietperiode in einer größeren Zeitperiode sucht. Dies wäre beispielsweise der Fall, wenn man innerhalb von den Sommerferien nur 1 Woche Urlaubszeit verbringen will und gleichzeitig die genaue Woche innerhalb der Ferien der Person unwichtig ist. In diesem Fall kann der obere Codeblock nicht verwendet werden. Stattdessen wird eine Lückensuche (gap search) durchgeführt. Genau diese Lückensuche hat die oben erwähnten Performance-Schwächen. Der Code für die Lückensuche ist etwas zu groß für diesen Artikel, deswegen bitte direkt im Script nachschlagen.

Die sonstigen Filter in der Suche sind relativ trivial und haben nur durch Umfang und nicht wegen Komplexität den Programmieraufwand beansprucht.