SUche + LiveSearch

Hier können Probleme und alles andere in Deutscher Sprache gelöst werden.
serels
Regular
Posts: 134
Joined: Wed Jan 07, 2009 11:13 am

SUche + LiveSearch

Post by serels »

Hi

Kann mir hier jemand sagen, wie ich die Suche (evt. inkl. LiveSearch) dazu bringe automagisch ALLE Begriffe zu suchen, die den eingegebenen Begriff beinhalten.
also eine *Begriff* Funktion annimmt ?

Es ist für Besucher ungewöhnlich und nicht nachvollziehbar, warum bei der Suche nach "Körper" keine Artikel mit Körperpsychotherapie oder Verkörperung ausgegeben werden, sondern ein lapidares inhaltliches "nichts gefunden", obwohl die Artikel mit diesen Begriffen nur so strotzen.

Das ist, so meine ich, suchmäßig unintelligent :?

lg serels
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Re: SUche + LiveSearch

Post by garvinhicking »

Hi!

Du müsstest irgendwie Deine Sucher darauf hinweisen, dass wenn Sie nach Teilstrings suchen wollen, am Ende des Wortes "*" nutzen. Also Körper*.

Google funktioniert übrigens auch so, das sucht nicht automatisch nach Teilstrings. Anders könnte man ja nicht exakt nach "Körper" suchen, da man dann immer auch Verkörperung usw. finden würde.

Grüße,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
onli
Regular
Posts: 2828
Joined: Tue Sep 09, 2008 10:04 pm
Contact:

Re: Suche + LiveSearch

Post by onli »

Das mag sein, aber dafür bietet die Suche nach "Körper" parallele Suchvorgänge an. Und Alternativen, falls Körper falsch geschrieben sein sollte. Auch ist das Problem bei Google nicht so gewichtig, da ja ein paar mehr Seiten indexiert wurden, während im Blog im Zweifel zum Kernbegriff genau gar nichts steht. Dazu: Wenn ich nach "müll papier" google wird schon auf der ersten Seite eine mit dem Titel "Papiermüll" angeboten. Die semantische Einordnung funktioniert bei Google wohl ganz gut, auch, wenn ich mit Kernbegriffen arbeite.

Daher hat mich das Verhalten der Suchfunktion in diesem Punkt auch schon irritiert.

Wäre es nicht möglich, so vorzugehen: Falls die Suche nach Körper wenige/keine Treffer findet wird das Ergebnis der Suche nach Körper* ausgegeben? Eventuell kann man die beiden Ergebnislisten auch optisch voneinander abtrennen und auf den Unterschied hinweisen:
"Die Suche nach Körper brachte 0 Ergebnisse
---------------------------------------------------------------
"Der Begriff Körper ist als Bestandteil in folgenden Artikeln enthalten:
"Körperwelten
..."
Vielleicht ist die Trennung sogar unnötig, da die Suchergebnisse des Kernwortes sowieso vorne stehen würden.
Gruß


PS: Nochmal zum Googleverhalten: Wenn man nach "onli" googlet findet man lauter "online"-Ergebnisse. (und only) Google sucht also nicht mehr nur nach Kernwörtern - was manchmal sehr nervig sein kann (gut, bei "onli" ist es verschmerzbar ;) ).
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Re: Suche + LiveSearch

Post by garvinhicking »

Hi!

Klar, grundsätzlich könnte man da mehrere Suchen anstoßen. Leider bin ich persönlich nicht so der Such-Fan, also falls da ein Programmierer ran will...gern! :-)

Grüße,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
onli
Regular
Posts: 2828
Joined: Tue Sep 09, 2008 10:04 pm
Contact:

Re: SUche + LiveSearch

Post by onli »

Wenn dagegen also nichts einzuwenden ist, schau ich mir den Code mal an (am we voraussichtlich).
serels
Regular
Posts: 134
Joined: Wed Jan 07, 2009 11:13 am

Re: SUche + LiveSearch

Post by serels »

onli wrote:Wenn dagegen also nichts einzuwenden ist, schau ich mir den Code mal an (am we voraussichtlich).
:-) Ich blicke dem mit Freuden entgegen :-)
lg serels
onli
Regular
Posts: 2828
Joined: Tue Sep 09, 2008 10:04 pm
Contact:

Re: SUche + LiveSearch

Post by onli »

Erinner mich am Zweifel dran ;)
An sich hab ich es aber in meinen Kalender eingetragen. Versprechen kann ich aber nichts, der Code ist noch zu sichten.
onli
Regular
Posts: 2828
Joined: Tue Sep 09, 2008 10:04 pm
Contact:

Re: SUche + LiveSearch

Post by onli »

So. Da ich heute überraschend Zeit hatte habe ich mir das mal angeguckt. Und eigentlich ist es recht simpel. Die neue Implementation funktioniert so: Wenn nicht nach "Suchbegriff*" gesucht wurde, "Suchbegriff" weniger als vier Ergebnisse findet, dann wird automatisch nochmal nach "Suchbegriff*" gesucht. Die Ergebnisse der Suche nach "Suchbegriff" landen auch bei der neuen Suche ganz oben.
So findet also die Suche nach "Papier" den "Papiermüll". Umgekehrt geht es aber nicht, "*Müll" findet ja auch jetzt den "Papiermüll" nicht.

Code: Select all

diff -Nur serendipity/include/functions_entries.inc.php /var/www/include/functions_entries.inc.php
--- serendipity/include/functions_entries.inc.php	2008-12-09 11:05:33.000000000 +0100
+++ /var/www/include/functions_entries.inc.php	2009-02-26 00:33:52.000000000 +0100
@@ -722,11 +722,13 @@
  * @access public
  * @param   string      The searchterm (may contain wildcards)
  * @param   int         Restrict the number of results [also uses $serendipity['GET']['page'] for pagination]
+ * @param   array       Add search Results at the top
  * @return  array       Returns the superarray of entries found
  */
-function &serendipity_searchEntries($term, $limit = '') {
+function &serendipity_searchEntries($term, $limit = '', $searchresults = '') {
     global $serendipity;
 
+    $orig_limit = $limit;
     if ($limit == '') {
         $limit = $serendipity['fetchLimit'];
     }
@@ -817,10 +819,34 @@
 
     $search =& serendipity_db_query($querystring);
 
-    if (is_array($search)) {
-        serendipity_fetchEntryData($search);
+    //Add param searchresults. serialize() seems to be necessary to make
+    //array_unique work.
+    if (is_array($searchresults)){
+        $search = array_merge($searchresults, $search);
+        foreach ($search as &$search_item){
+            $search_item=serialize($search_item);
+        }
+        $search=array_unique($search);
+        foreach ($search as &$search_item){
+            $search_item=unserialize($search_item);
+        }
     }
 
+    //if * wasn't already appended and if there are none or not enough
+    //results, search again for entries containing the searchterm as a part  
+    if (strpos($term, '*') === false) {
+        if (! is_array($search)) {
+            return serendipity_searchEntries($term.'*', $orig_limit);
+        }else if (count($search) < 4){
+            return serendipity_searchEntries($term.'*', $orig_limit, $search);
+        }
+    }
+    
+    if (is_array($search)){
+        serendipity_fetchEntryData($search);
+    }
+    
+    
     return $search;
 }
Gruß
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Re: SUche + LiveSearch

Post by garvinhicking »

Hi!

Das sieht doch schonmal vielversprechend aus. Das serialize() jedoch hat's mir noch nicht richtig angetan, das müsste man doch anders lösen können. Eigentlich musst Du ja nur über $search[x]['id'] den Vergleich machen, alle anderen Array-Keys sind ja eher irrelevant. Sprich, man müsste einfach über das neue und das alte Searchresult einmal drüber foreach'en, sich die $array['id'] rausnehmen und zwischenspeichern, und dann nur die Elemente vom alten $search array rübernehmen, die nicht in der Liste vorhandener neuer Searchresults ist...?

Grüße,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
onli
Regular
Posts: 2828
Joined: Tue Sep 09, 2008 10:04 pm
Contact:

Re: SUche + LiveSearch

Post by onli »

Ja, so funktioniert es auch - oder hast du einen weniger komplexen Weg im Kopf?

Code: Select all

if (is_array($searchresults)){
    foreach ($searchresults as $old_results) {
        foreach ($search as $new_results) {
            if ($old_results['id'] == $new_results['id']) {
                $pos=array_search($new_results,$search);
                unset($search[$pos]);
                break;
            }
        }
    }
    $search = array_merge($searchresults, $search);
}
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Re: SUche + LiveSearch

Post by garvinhicking »

Hi!

Ich kann das leider jetzt nicht coden, aber ich würde vorher $id_new = array() und danach $id_old = array() belegen, so dass man immer nur zwei foreach-schleifen hatt statt n*n foreachschleifen, das performt so wesentlich schlechter.

Grüße,
GArvin
onli wrote:Ja, so funktioniert es auch - oder hast du einen weniger komplexen Weg im Kopf?

Code: Select all

if (is_array($searchresults)){
    foreach ($searchresults as $old_results) {
        foreach ($search as $new_results) {
            if ($old_results['id'] == $new_results['id']) {
                $pos=array_search($new_results,$search);
                unset($search[$pos]);
                break;
            }
        }
    }
    $search = array_merge($searchresults, $search);
}
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
onli
Regular
Posts: 2828
Joined: Tue Sep 09, 2008 10:04 pm
Contact:

Re: SUche + LiveSearch

Post by onli »

Durch das break sollte die Komplexität kleiner n*n sein - natürlich nicht im worst case. Gut, ich bin mir nicht sicher wie stark man array_search einrechnen muss, eigentlich führt das sogar zum n³ im worst-case.

Aber das kann man ja rausnehmen. Weniger als das hier kann eigentlich nicht gehen, aber ich bin gespannt, was du mit dem array-erstellen meintest.

Code: Select all

    if (is_array($searchresults)){
        for ($i=0;$i<count($searchresults);$i++){
            for ($j=0;$j<count($search);$j++){
                if ($searchresults[$i]['id'] == $search[$j]['id']){
                    unset($search[$j]);
                    break;
                }
            }
        }
        $search = array_merge($searchresults, $search);
    }
Gruß
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Re: SUche + LiveSearch

Post by garvinhicking »

Hi!

Ich dachte an sowas (untested):

Code: Select all

if (is_array($searchresults)) {
    $ids_current = array();
    foreach($searchresults AS $idx => $data) {
        $ids_current[$data['id']] = true;
    }
    
    foreach($search AS $idx => $data) {
        if (isset($ids_current[$data['id']])) {
            unset($search[$idx]);
            break;
        }
    }
    $search = array_merge($searchresults, $search);
}
Grüße,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
onli
Regular
Posts: 2828
Joined: Tue Sep 09, 2008 10:04 pm
Contact:

Re: SUche + LiveSearch

Post by onli »

Ja - das sieht zwar so aus, als wäre das besser. Aber da isset ja auch das Array durchgehen muss sollte sich das nichts nehmen. So versteckt man nur das zweite for in einem Funktionsaufruf.
Gruß
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Re: SUche + LiveSearch

Post by garvinhicking »

Hi!
onli wrote:Ja - das sieht zwar so aus, als wäre das besser. Aber da isset ja auch das Array durchgehen muss sollte sich das nichts nehmen. So versteckt man nur das zweite for in einem Funktionsaufruf.
Gruß
Nee, isset prüft nur exakt auf einen festen Array-Schlüssel, da wird dann nicht mehr durchwandert. Durch die direkte Array-Adressierung mit einem festern Wert kann PHP direkt an die entsprechende Speicherstelle springen und den Arraywert holen.

Grüße,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
Post Reply