[php/mysql] Zeer goede search

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Voorm ijn profielen site wil ik een goede search engine bouwen, daar mijn site bijna geheel gebasseerd is op deze search engine. Nu heb ik bijna alles klaar, ik moet alleen de profielen nog goed uit mijn database halen. Ik moet dus alleen nog goede queries maken om de profielen met juiste relevantie uit de database te halen. Nu heb ik eigenlijk geen benul van goede queries. Ik heb nu een LIKE query. FULL TEXT heb ik al geprobeerd, maar dat was niet echt goed volgens mij.

Stel nu dat ik een aantal eigenschappen van een profiel heb. Zoals haar kleur, kleur ogen etc etc.. en nog een text vak met info die die persoon zelf kan invullen. Hoe kan ik dan het beste de queries maken. Dus de zoekterm opsplitsen en in welke volgorde en hoe geef ik relevantie aan de resultaten. Dus waar kan ik het beste op ordenen etc etc.. iemand tips en dergelijkle?

Acties:
  • 0 Henk 'm!

  • Spooksel
  • Registratie: Oktober 2000
  • Laatst online: 17:27

Spooksel

Spooksel!

mysql kan meerdere zoekcriteria aan doormiddel van: AND en OR! (Bedoel je dit?)

Zoeken op haar/oogkleur is niet zo moeilijk, das gewoon vergelijkwerk, zoeken op termen uit de info die ze invullen:
PHP:
1
$sql = "SELECT * FROM profiel WHERE info LIKE %".$zoekterm."%";

Dit is natuurlijk wel een beetje een ranzige query omdat als je nu op "e" zoekt oid dan krijg je natuurlijk IEDERE row terug in je query... maar het idee is er :)

Bevalt mijn schrijfsel je niet? www.korrelatie.nl


Acties:
  • 0 Henk 'm!

Verwijderd

Spooksel schreef op 04 mei 2004 @ 18:07:
Dit is natuurlijk wel een beetje een ranzige query omdat als je nu op "e" zoekt oid dan krijg je natuurlijk IEDERE row terug in je query... maar het idee is er :)
Maak je gewoon een dropdown waaruit je kleuren kan kiezen of zeg je in PHP dat de zoektekst groter moet zijn dan 3 tekens ofso.
k ben het verder idd eens met Spooksel. Gewoon vaak AND en OR gebruiken.

code:
1
$sql = "SELECT * FROM profiel WHERE haarkleur LIKE '%".$_POST['haarkleur']."%' OR oogkleur LIKE '%".$_POST['oogkleur']."%'";

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Ik neem aan dat voor de kleur ogen en haar maar enkele opties aanwezig zijn en je daarvoor een ENUM gebruikt? Dan is het het beste om in het zoek formulier voor deze velden een selectbox neer te zetten, waarin de (eventueel meedere) kleur gekozen kan worden. Dan kun je dit simpel weg in je query verwerken door iets als dit:
code:
1
"WHERE `kleur_ogen`='" .  $_POST['kleur_ogen'] . "' AND `kleur_haar`='" . $_POST['kleur_haar'] . "'"

In je selectbox geef je dan iedere option steeds de juiste value mee voor de kleur zodat je dit zo direct in de query kunt invullen.

Dan over je relevantie, dat is alleen mogelijk door gebruik te maken van een full text search helaas. Alhoewel helaas, full text is een geschenk imo. Voorbeeldje van hoe je dit kunt doen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT 
  id, 
  MATCH(full_text) AGAINST ('keyword' IN BOOLEAN MODE) AS relevantie 
FROM 
  table 
WHERE 
  MATCH(full_text) AGAINST ('keyword' IN BOOLEAN MODE) 
AND 
  relevantie > 0.2
LIMIT
  100
ORDER BY
  relevantie
DESC

Ik hoop dat je het idee een beetje vat. Kijk anders een in de MySQL manual, daar kun je wel wat meer info vinden.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
Michali schreef op 04 mei 2004 @ 18:14:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT 
  id, 
  MATCH(full_text) AGAINST ('keyword' IN BOOLEAN MODE) AS relevantie 
FROM 
  table 
WHERE 
  MATCH(full_text) AGAINST ('keyword' IN BOOLEAN MODE) 
AND 
  relevantie > 0.2
LIMIT
  100
ORDER BY
  relevantie
DESC

Ik hoop dat je het idee een beetje vat. Kijk anders een in de MySQL manual, daar kun je wel wat meer info vinden.
LET OP! de boolean mode werkt pas bij MySQL >=4.0 !!

Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ik heb die manual mode al doorgelezen. Maar ik wil het eigenlijk net zo een beetje als google hebben.

1 zoekbox, en als je bijv blauwe ogen in tikt dat hij dan alle profielen met blauwe ogen erin uithaalt. Dus als er bijv een zin is van mijn ogen zijn blauw.. dat deze dan ook gevonden worden.

Ik heb het een en ander doorgelezen en mijn conclusie was door de reacties hier op het forum, dat full text search traag is.

Ik heb het een en ander getest en als ik bijv zoek op blauwe ogen met behulp van fulltext dan pakt hij deze niet. Als ik het met LIKE doe, dan pakt hij hem weer wel. Dus ik vraag me af wat ik het beste kan doen. Wel full text of beter iets anders. Zoals bijv als erop man met blauwe ogen wordt gezocht.. hij deze knipt en dan er een volgende query van maakt
%man met blauwe ogen% or %man%met%blauwe%ogen%

en misschien nog een paar, maar welke?

Acties:
  • 0 Henk 'm!

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 18:44

gorgi_19

Kruimeltjes zijn weer op :9

Ik heb het een en ander doorgelezen en mijn conclusie was door de reacties hier op het forum, dat full text search traag is
Traag? :? 't is iig sneller dan met like's aan de gang gaan.

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Acties:
  • 0 Henk 'm!

  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Misschien iets om mee te nemen: als een woord met '=' niet gevonden wordt pas 'LIKE' gebruiken. Voorkomt (te) veel resultaten en zelfs bij typefouten kunnen er goede resultaten zijn.

Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
ja ik kwam een paar posts tegen die dat zeiden.. dus dat is niet waar?

En ik had iets van 5 velden als fulltext gedeclareerd (varchar en text), maar als ik dan iets doe als:

code:
1
2
3
4
$query1 = mysql_query("SELECT * FROM users WHERE MATCH (moreinfo,username) AGAINST ('$q')");
while ($row = mysql_fetch_array($query1)) {
    $suid = $row["uid"];
}


Geeft hij een mysql_fetch_array error??? terwijl als ik username weghaal hij het wel goed doet. Beide table zijn fulltext en username is ook uniek. als ik username vervang door country wat ook een full textveld is. geeft hij ook dezelfde error.


Ik wil dus eigenlijk al die textvelden als fulltext declareren en dan een full text search doen icm met relevantie zoals hierboven beschreven is. Is dat wat?

[ Voor 15% gewijzigd door RSD op 04-05-2004 19:13 . Reden: aanvulling ]


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Doe eens een query op deze manier:
PHP:
1
$result = mysql_query($query) or die(mysql_error());

Dan zie je snel wat er mis is als er iets mis is.

Weet je zeker dat je een full text index met de naam `moreinfo,username` hebt?

Anders moet je dit ook even toevoegen:
code:
1
2
3
4
5
6
7
8
ALTER TABLE
  `table`
ADD FULL_TEXT 
  `moreinfo,username` 
  ( 
    `moreinfo`, 
    `username`
  )

Of iets in die geest. Ik denk dat de fout licht bij het feit dat je twee losse indexen hebt gelegd en niet 1 voor beide velden.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
In phpMyAdmin klik ik voor die velden op de optie fulltext en dan zegt hij dat het goed is? Kan dit niet dan?

Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ik krijg het niet voor elkaar... ik doe nu de query:

code:
1
2
3
4
5
6
7
8
9
10
ALTER TABLE
  users
ADD FULL_TEXT 
  moreinfo,username,country,city 
  ( 
    moreinfo, 
    username,
    country,
    city
  )


Ik kan in phpMyAdmin die velden wel full text krijgen, maar dan heb ik het probleem zoals hierboven, dat ik maar in 1 kollom kan zoeken.

Acties:
  • 0 Henk 'm!

Verwijderd

volgens mij heeft een fulltext index erg weinig zin op een column als username, country of city, aangezien dat meestal enkele woorden zijn...

(of praat ik nu echt onzin...)

Kun je niet beter een grote index maken van alle columns als haarkleur, oogkleur, city, country etc en dan gewoon 1 grote where maken (en eventueel 'AND oogkleur LIKE '%' toevoegen)?

[ Voor 35% gewijzigd door Verwijderd op 05-05-2004 11:27 ]


Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Nou ik heb nu gemerkt dat als ik die kollomen als full text doe en ook meeneem en er wordt gezocht op een username, dan verschijnt deze wel, dus volgensmij is het best handig om alle info als full text te doen...

Mijn host heeft alleen nog geen mysql 4.0.1 of hoger lopen volgens mij dus het boolean gebeuren en het relevantie gebeuren kan dus niet volgens mij...

Echter heb ik hem gemaild en nog niks terug gehad, misschien zijn ze nu bezig om die te installeren.

Als ik nu geen mysql 4.0.1 of hoger kan krijgen, zijn er dan manieren om een relevantie aan de zoekresultaten mee te geven?

Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
RSD schreef op 05 mei 2004 @ 13:36:
Nou ik heb nu gemerkt dat als ik die kollomen als full text doe en ook meeneem en er wordt gezocht op een username, dan verschijnt deze wel, dus volgensmij is het best handig om alle info als full text te doen...

Mijn host heeft alleen nog geen mysql 4.0.1 of hoger lopen volgens mij dus het boolean gebeuren en het relevantie gebeuren kan dus niet volgens mij...

Echter heb ik hem gemaild en nog niks terug gehad, misschien zijn ze nu bezig om die te installeren.

Als ik nu geen mysql 4.0.1 of hoger kan krijgen, zijn er dan manieren om een relevantie aan de zoekresultaten mee te geven?
Ja! misschien handig om toch DEZE PAGINA even door te lezen :?

Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ja wat is het nu, .. in dat voorbeeld gebruiken ze ook de title en de body als full text ???

Is het nu wel of niet verstandig om die kollomen op full text te zoeken, waar info in staat over die persoon, zoals leeftijd, etc...

Ik heb die pagina gelezen.. vanmorgen al, maar ik heb hem net nog een keer doorgelezen en ben erachter gekomen, dat je voor de relevantie dus geen BOOLEAN nodig hebt... logisch eigenlijk, want BOOLEAN is voor die + en die - etc..

Zijn er nog meer suggestie die ik eventueel extra kan doen om een search te optimaliseren?

Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
Als er informatie in die velden zit waar jij in wilt zoeken moet je ze meenemen.

code:
1
WHERE MATCH (moreinfo,username) AGAINST ('amsterdam') AND city='Amsterdam'

code:
1
WHERE MATCH (moreinfo,username,city) AGAINST (amsterdam)

code:
1
WHERE MATCH (moreinfo,username) AGAINST (amsterdam) and city like '%amsterdam%'


Probeer het verschil te begrijpen. De laatste optie is zeker geen goede, omdat de tabel in het veld city alsnog helemaal doorgezocht moet worden op 'amsterdam'. (zonder index, dus langzaam)

Als je zeker weet dat city amsterdam moet worden dan kun je de eerste gebruiken, die is dan het meest optimaal.
In alle andere gevallen is (Just my 2 cents) de tweede optie de beste.

Het enige wat je je kunt afvragen is hoe RELEVANT het is om bijvoorbeeld in een veld als username te zoeken met een fulltext of een like constructie. Ik kan me weinig echt relevant constructies voorstellen....

[ Voor 5% gewijzigd door beetle71 op 05-05-2004 14:37 ]


Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Nou ik heb 1 zoekbalk daar kunnen ze woorden invullen. Mijn zoekmachine moet dan de beste resultaten die het meest daar mee overeenkomen uit mijn database halen en bovenaan zetten. Als ze bijv amsterdam intikken, dan weet mijn script niet dat het om een city gaat, dus daarom neem ik al die velden mee...

Nou nog iets..

Als iemand gezocht heeft,moet ik die resultaten tonen, nu ben ik ooit op dit forum eens een scriptje tegengekomen die dat doet, dus de boel opsplitst met het zoekwoord erin en dan 2 woorden ervoor en erna en dan wat puntjes en weer wat woorden, net zoals google en de search op dit forum... weet iemand waar ik dat kan vinden of hoe ik zoiets het beste kan maken?

Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ik heb dit gemaakt om het te tonen, alleen werkt het niet goed:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function makeresults($text,$word) {
    $results = "";
    $array = explode(" ",$text); 
    for ($i = 0;$i < count($array);$i++) { 
        
        if ($i >= 0 && $i <= 7) {
            $results .= $array[$i]." ";
        }

        if ($i > 7) {
            if ($array[$i] == $word) {
                if ($i>11) {
                    $results .= " ... ".$array[$i-4]." ".$array[$i-3]." ".$array[$i-2]." <b>".$array[$i]."</b> ".$array[$i+1]." ".$array[$i+2] ; 
                } elseif ($i>7 or $i <=11) {
                    $results .= $array[8]." ".$array[9]." ".$array[10]." ".$array[11];
                }
            }
        }
    }
    echo $results;
}


Deze functie zou dus de resultaten zoals google ze neerzet moeten tonen.
Dus bijv.. sowieso de eerste 7 woorden erna de gezocht woorden met 3 woorden ervoor en erna. Nu kom ik in de problemen als het 12e woord een zoekwoord is met overlapping ed. Iemand misschien een algoritme zodat ik geen overlap krijg en er een soot grenss van 2 of 3 woorden om het zoekwoord heen zit.. en als je bijv zoekwoord en zoekwoord hebt, dat hij dan ook geen overlapping krijgt, dus 2 dezelfde woorden naast elkaar.

Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Niemand die een idee heeft hoe zoiets nu goed in elkaar steekt? Ik ben ook weer wat aan het prutsen geweest, maar nog steeds niet iets dat alle soorten etxt aan kan, dus als er 2 woorden binnen de grens zitten etc etc..

De bedoeling is om een stuk text als:

bla1 bla2 bla3 bla4 bla5 bla6 bla7 keyword1 bla8 bla9 bla10

om te zetten naar:

...bla5 bla6 bla7 keyword1 bla8 bla9 ...

en om de text:

bla1 bla2 bla3 bla4 bla5 bla6 bla7 keyword1 bla8 keyword1 bla9 bla10

om te zetten naar:

...bla5 bla6 bla7 keyword1 bla8 keyword1 bla9 ...

of iets soortgelijks op deze manier.

Er moet iets met die grens gebeuren van x woorden ervoor en y woorden erna, en als het woord binnen die grens ligt, moeten de grensen z groter worden gemaakt, maar ik zie niet hoe ik dit kan doen in php.

Acties:
  • 0 Henk 'm!

  • ripexx
  • Registratie: Juli 2002
  • Laatst online: 17:49

ripexx

bibs

Als je het nu eens netjes uitschrijft en dan omzet naar code is het toch geen probleem?

Je het een string/stuk text welke het resultaat bevat van een zoek query. De wil de worden waarop gezocht is terug laten komen in een korte beschrijving. Nou dan kan je toch gewoon de regels opzetten :)

buit is binnen sukkel


Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Volgens mij moet zoiets met een recursieve functie. Maar het is voor mij heel lang geleden hoe dat ook alweer ging. Het is een functie aanroep in een functie. Ik wete niet eens of php dat ondersteunt, maar op die manier kan het volgens mij. maar ik zou echt niet weten hoe ik dat moet doen..

Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
RSD schreef op 06 mei 2004 @ 12:03:
Volgens mij moet zoiets met een recursieve functie. Maar het is voor mij heel lang geleden hoe dat ook alweer ging. Het is een functie aanroep in een functie. Ik wete niet eens of php dat ondersteunt, maar op die manier kan het volgens mij. maar ik zou echt niet weten hoe ik dat moet doen..
Recursieve functie hiervoor :? Ik kan me niet voorstellen hoe je dat hier nuttig in wilt zetten....
Overigens kan het wel in php.

In de meest simpele gedachte:

- explode de hele tekst op het gezochte woord, je hebt nu een array met blokjes die tussen(voor/achter) de zoekwoorden stonden.

- neem van het eerste element in de array (indien er voldoende inzit) de laatste paar woorden/tekens.

- zet daat het zoekwoord achter,

- neem nu de eerste paar woorden van het volgende element.. enz enz......

Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ja zoiets had ik al in mn eigen gemaakt functie. Ik kan wel een functie maken voor 1 zoekwoord, maar als er meerdere dezelfde zoekwoorden bij elkaar in de buurt zitten, dus binnen de overlapping van het eerste zoekwoord, dan werkt het al niet meer.

dus als ik "bla1 bla2 bla3 keyword bla4" heb dan kan het wel, maar als ik 2 dezelfde keywords naast elkaar heb, dan heb ik een probleem.

ik heb nu:
PHP:
1
2
3
4
function makeresults($result_text,$num_words=10) { 
    $text_array = explode(" ",$result_text,$num_words+1); 
    return implode(" ", array_slice($text_array,0,$num_words)."..."; 
}

Acties:
  • 0 Henk 'm!

  • ripexx
  • Registratie: Juli 2002
  • Laatst online: 17:49

ripexx

bibs

RSD schreef op 06 mei 2004 @ 12:50:
Ja zoiets had ik al in mn eigen gemaakt functie. Ik kan wel een functie maken voor 1 zoekwoord, maar als er meerdere dezelfde zoekwoorden bij elkaar in de buurt zitten, dus binnen de overlapping van het eerste zoekwoord, dan werkt het al niet meer.

dus als ik "bla1 bla2 bla3 keyword bla4" heb dan kan het wel, maar als ik 2 dezelfde keywords naast elkaar heb, dan heb ik een probleem.

ik heb nu:
PHP:
1
2
3
4
function makeresults($result_text,$num_words=10) { 
    $text_array = explode(" ",$result_text,$num_words+1); 
    return implode(" ", array_slice($text_array,0,$num_words)."..."; 
}
Dan zal je die uitzonderingen moeten afvangen. Stel eerst eens een aantal regels op en ga die daarna uitwerken.
Om je nog even op weg te helpen:
[list]
• Zoek het eerste zoekwoord in de array
• In dien je zoekwoord vaker voorkomt doe b anders
• Maak een nieuwe string .. + 3 woorden + zoekwoord + 3 woorden + ...
• etc. etc

Daarmee moet je toch wel een universele functie kunnen maken. :)

buit is binnen sukkel


Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ja ok, dat had ik al, maar dat laatste is juiste het probleem. Stel nu dat er meerdere zoekwoorden inzitten. Ik druk nu 3 woorden erna en 3 woorden ervoor af. Dat lukt me ook nog wel, maar wat als er zoekwoorden bij elkaar in de buurt zitten, dus binnen die 3 woorden... bij mijn functie krijg ik dan 2x dezelfde woorden ervoor en erna, met ... ertussen.

Ik had hier wat gevonden:

http://www.phpbuilder.com...tid=10365247#post10365247 alleen deze krijg ik niet aan de praat, dit is de ideale volgens mij...

Acties:
  • 0 Henk 'm!

  • ripexx
  • Registratie: Juli 2002
  • Laatst online: 17:49

ripexx

bibs

RSD schreef op 06 mei 2004 @ 13:25:
Ja ok, dat had ik al, maar dat laatste is juiste het probleem. Stel nu dat er meerdere zoekwoorden inzitten. Ik druk nu 3 woorden erna en 3 woorden ervoor af. Dat lukt me ook nog wel, maar wat als er zoekwoorden bij elkaar in de buurt zitten, dus binnen die 3 woorden... bij mijn functie krijg ik dan 2x dezelfde woorden ervoor en erna, met ... ertussen.

Ik had hier wat gevonden:

http://www.phpbuilder.com...tid=10365247#post10365247 alleen deze krijg ik niet aan de praat, dit is de ideale volgens mij...
Even een paar zaken gescheiden houden.

Bepaal eerste zoekwoord enz enz.
Kijk wel state je de output wil verkrijgen.
[list]
• Is het zoekwoord het eerste woord
• Is het zoekwoord het laatste woord
• Komt het zoekwoord vaker voor

Bepaal gewoon even op papier wat de status van dit alles is. Het script waar jij naar verwijst werkt met de maximale lengte van een string zodaning dat je tabellen niet uitrekken. Verder zijn er hier op GoT ook genoeg varianten van te vinden. http://gathering.tweakers...5BxDB%5D=default#hitstart

[ Voor 3% gewijzigd door ripexx op 06-05-2004 13:33 ]

buit is binnen sukkel


Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
Ach,.... rustig middagje, en ik heb het zelf heel binnenkort ook nodig dus......
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
$text='AMSTERDAM - De politie in Amsterdam is op zoek naar automobilisten die 
een kentekenplaat missen. Het personeel van een autowasstraat leverde 
woensdag zeven kentekenplaten af bij de politie die bij een wasbeurt waren 
achtergebleven. 

Het gebeurt volgens de politie met grote regelmaat dat de kentekenplaten in de 
wasstraat achterblijven. "Als iemand een kentekenplaat mist is het verstandig 
even na te gaan of die mogelijk in een wasstraat is achtergebleven. Het scheelt in 
ieder geval een hoop administratieve rompslomp", zegt de politie. 

Het verlies van de nummerborden kan simpel voorkomen worden door ze met een 
paar extra schroeven vast te zetten, aldus de politie. Sommige eigenaren van de 
terug gevonden nummerborden hadden al aangifte gedaan van vermissing.';


$words=explode(' ',$text);
$zoekwords=array('politie','regelmaat','eigenaren');

$output='';
$num_words=3; // aantal woorden voor en na
$lasthit=false;

foreach($words as $key => $word){
    // alle leestekens weghalen...
    $word=preg_replace('/[\.\,\:\;]$/','',$word); 
    if(in_array($word,$zoekwords)){
        // zoekwoord match
        if($lasthit===false || $key-$num_words>$lasthit){
            $output.="&nbsp;&nbsp;  ...";
            // laat de laatste x woordjes hiervoor zien
            for($i=$num_words;$i>0;$i--){
                if(isset($words[$key-$i])){
                    $output.=' '.$words[$key-$i];
                }
            }
            $output.=' <span class="rood">'.$words[$key].'</span>';
        } else {
            // we zijn nog actief... dus alleen huidig woord tonen.
            $output.=' <span class="rood">'.$words[$key].'</span>';
        }
        $lasthit=$key;
    } else {
        // nog x extra laten zien.
        if($lasthit!==false){
            if($key-$num_words<=$lasthit){
                $output.=' '.$word;
            }
             if($key-$num_words==$lasthit){
                $output.=" ...&nbsp;&nbsp;";
            }
        }
    }
}
echo $output;

[ Voor 9% gewijzigd door beetle71 op 06-05-2004 15:16 ]


Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Hmm dat werkt lekker :-) alleen ik vraag me af , die ===false , moet dat geen == zijn? Hij geeft geen error, dus het zal wel niet, maar ik ben dat nog nooit tegen gekomen eerlijk gezegd..

Acties:
  • 0 Henk 'm!

  • ripexx
  • Registratie: Juli 2002
  • Laatst online: 17:49

ripexx

bibs

RSD schreef op 06 mei 2004 @ 15:23:
Hmm dat werkt lekker :-) alleen ik vraag me af , die ===false , moet dat geen == zijn? Hij geeft geen error, dus het zal wel niet, maar ik ben dat nog nooit tegen gekomen eerlijk gezegd..
Er is een wezenlijk verschil tussen == en === zie maar eens hier: http://www.php.net/manual....operators.comparison.php

Verder heeft de vergelijking weinig nut aangezien je de boolean FALSE toewijst aan een variabele zou een boolean vergelijking een stuke minder fout gevoelig zijn. :)

[ Voor 18% gewijzigd door ripexx op 06-05-2004 15:32 ]

buit is binnen sukkel


Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Hij is ook nog case sensitive en de eerste puntjes moeten er niet staan in sommige gevallen dan, als het zoekwoord binnen de eerste grens is.

Verder werkt het perfect..

[ Voor 10% gewijzigd door RSD op 06-05-2004 15:36 ]


Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?
$text='AMSTERDAM - De politie in Amsterdam is op zoek naar automobilisten die 
een kentekenplaat missen. Het personeel van een autowasstraat leverde 
woensdag zeven kentekenplaten af bij de .politie. die bij een wasbeurt waren 
achtergebleven. 

Het gebeurt volgens de politie politie -politie- (){}[]+_-"\'tie met grote regelmaat dat de kentekenplaten in de 
wasstraat achterblijven. "Als (iemand) een kentekenplaat mist is het verstandig 
even na te gaan of die mogelijk in een wasstraat is achtergebleven. Het scheelt in 
ieder geval een hoop administratieve rompslomp", zegt de politie. 

Het verlies van de nummerborden kan simpel voorkomen worden door ze met een 
paar extra schroeven vast te zetten, aldus de politie Sommige eigenaren van de 
terug gevonden nummerborden hadden al politie aangifte gedaan van vermissing.'; 


$words=explode(' ',$text); 
$zoekwords=array('politie','regelmaat','eigenaren'); 

$output=''; 
$num_words=3; 
$lasthit=false; 

foreach($words as $key => $word){ 
    // alle leestekens weghalen... 
    $word=preg_replace('/[\.\,\:\;]$/','',$word); 
    if(in_array($word,$zoekwords)){ 
        // zoekwoord match 
        if($lasthit===false || $key-$num_words>$lasthit){ 
            if ($key-$num_words == 0) {
                $output.="";
            } else {
                $output.="..."; 
            }
            // laat de laatste x woordjes hiervoor zien 
            for($i=$num_words;$i>0;$i--){ 
                if(isset($words[$key-$i])){
                    
                    $output.=' '.$words[$key-$i]; 
                } 
            } 
            $output.=' <b>'.$words[$key].'</b>'; 
        } else { 
            // we zijn nog actief... dus alleen huidig woord tonen. 
            $output.=' <b>'.$words[$key].'</b>'; 
        } 
        $lasthit=$key; 
    } else {
        // nog x extra laten zien. 
        if($lasthit!==false){ 
            if($key-$num_words<=$lasthit){ 
                $output.=' '.$word; 
            } 
            if($key-$num_words==$lasthit){ 
                $output.="..."; 
            } 
        } 
    } 
}
$output = str_replace("......"," ...",$output);
echo $output;
?>


Ik heb nog een klein iets toegevoegd, zodat het eerste woord wel/geen puntjes heeft en dat de 6 punten worden vervangen door ... punten. Het kan vast makkelijker... dat aller laatste, iemand ideen? ik dacht zoiets van

if ($key-$num_words==count($words)) {
$output .= ""
} else {
$output .= "...";
}

alleen ik weet niet waar dit te plaatsen, omdat $words anders is dan de array, komt niet helemaal overeen dus zal hij soms de laatste woorden weglaten.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Overigens is een relationele database eigenlijk helemaal niet geschikt om documenten mee te indexeren zodat je kunt zoeken. Dat is ook de hele reden waarom de search @ GoT altijd zo traag was en dat er nu een extern systeem gebruikt wordt

[ Voor 32% gewijzigd door .oisyn op 06-05-2004 17:37 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
RSD schreef op 06 mei 2004 @ 17:09:
[SNIP]

Ik heb nog een klein iets toegevoegd, zodat het eerste woord wel/geen puntjes heeft en dat de 6 punten worden vervangen door ... punten. Het kan vast makkelijker... dat aller laatste, iemand ideen? ik dacht zoiets van

if ($key-$num_words==count($words)) {
$output .= ""
} else {
$output .= "...";
}

alleen ik weet niet waar dit te plaatsen, omdat $words anders is dan de array, komt niet helemaal overeen dus zal hij soms de laatste woorden weglaten.
Uggeugge... ahum.... :'(
Als je nu eens geen puntjes meer zet achter elk blokje.... maar alleen helemaal aan het einde nog drie puntjes aan de definitieve $output toevoegd?!?!

en ook de case sensitivity is een eitje.. zorg dat je zoekwoorden altijd onderkast zijn, of zet ze daarnaar om, en doe dan:
PHP:
1
2
if(in_array(strtolower($word),$zoekwords)){
.....


Klein beetje zelf freubelen moet nog wel lukken toch ;)

Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Hmm welk systeem zou ik dan moeten gebruiken, een oracle database? Voorlopig is het wel ff goed, de site is straks nog klein en als hij eventueel iets groter zou worden en het problemen gaat opleveren kan ik de boel wel omzetten naar iets anders en eventueel een betaald iets nemen, maar zover is het nog lang niet!

Over die output, bij google zie je tussendoor ook ... staan en niet alleen aan het einde.. of begrijp ik je nu verkeerd?

[ Voor 19% gewijzigd door RSD op 06-05-2004 21:23 ]


Acties:
  • 0 Henk 'm!

  • Kippenijzer
  • Registratie: Juni 2001
  • Laatst online: 26-08 09:08

Kippenijzer

McFallafel, nu met paardevlees

.oisyn schreef op 06 mei 2004 @ 17:36:
Overigens is een relationele database eigenlijk helemaal niet geschikt om documenten mee te indexeren zodat je kunt zoeken. Dat is ook de hele reden waarom de search @ GoT altijd zo traag was en dat er nu een extern systeem gebruikt wordt
Is er hiervoer een topic, of zou je hier iets meer info over kunnen geven, als in, hoe ik me dit precies voor moet stellen? Op wat voor manier werkt de externe database in dit geval (en hoe verzamelt hij zijn/haar info?)

Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
XML ofzo?

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Kippenijzer schreef op 06 mei 2004 @ 21:36:
[...]

Is er hiervoer een topic, of zou je hier iets meer info over kunnen geven, als in, hoe ik me dit precies voor moet stellen? Op wat voor manier werkt de externe database in dit geval (en hoe verzamelt hij zijn/haar info?)
Zie bijvoorbeeld http://www.xapian.org/
Dat is het systeem dat hier ook draait. Het punt met een relationele database is dat het vooral geschikt is voor een vrij recht-toe-recht-aan structuur, zoals bijvoorbeeld een forum. Een forum heeft meerdere topics, en een topic heeft meerdere berichten, enz.

Indexering van een tekst is anders. Als je even uitgaat van een database zonder FULL TEXT optie (of die je gewoon niet gebruikt), dan ga je woorden indexeren. Dat is geloof ik de default search van React zelf, en heb ik ook in mijn eigen forum geimplementeerd. Als er een stuk tekst bij komt waarop gezocht kan worden, dan deel je die tekst op in woorden, en dan ga je een word_id koppelen aan elk van die woorden. Je hebt dan zeg maar een tabel met zoekwoorden, als een woord er al in staat kun je het word_id natuurlijk opvragen, en anders is het een nieuw woord en moet je het invoegen. Vervolgens hou je per topic/artikel/whatever een lijst met woorden bij. Als je de gebruiker laat zoeken, dan zoek je de word_id's op van de opgegeven zoekwoorden, en je rapporteert gewoon alle dingen waar die woorden in staan.

Dit is voor een kleine site wel te doen, maar voor een wat grotere site lopen de zoektabellen al snel uit de hand. Bovendien kun je alleen nog maar zoeken op individuele woorden. Queries zoals iets waar wel een bepaald woord in voor mag komen, maar waar weer niet een ander woord in voor mag komen, zijn wel mogelijk, maar wordt al snel ingewikkeld. En queries als "alle artikelen met woord1 in de buurt van woord2" zijn helemaal niet mogelijk. Het updaten van zo'n database is ook best een rompslomp, bijvoorbeeld als er iets wijzigt in een artikel.

Natuurlijk kennen databases wel iets als text indexing, maar eigenlijk zijn ze daar gewoonweg niet voor bedoeld, en kun je ze er dus ook maar beter niet voor gebruiken. Een systeem dat speciaal gericht is op dat doel en dat dus bijhoudt welke woorden waarin voorkomen, en ook waar ze in het artikel voorkomen (bijvoorbeeld: in de titel, of 15e woord in het artikel, etc) is geoptimaliseerd voor deze structuur, en kan dan ook veel sneller zoeken met veel uitgebreidere criteria dan een normale relationele database.

Hoe het systeem verder z'n data opslaat is niet interessant, net als dat niet interessant is hoe een database z'n tabellen opslaat, als het maar efficient gebeurt :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
RSD schreef op 06 mei 2004 @ 21:22:
Hmm welk systeem zou ik dan moeten gebruiken, een oracle database? Voorlopig is het wel ff goed, de site is straks nog klein en als hij eventueel iets groter zou worden en het problemen gaat opleveren kan ik de boel wel omzetten naar iets anders en eventueel een betaald iets nemen, maar zover is het nog lang niet!

Over die output, bij google zie je tussendoor ook ... staan en niet alleen aan het einde.. of begrijp ik je nu verkeerd?
als je het weghaalt dat ie NA elk groepje ... zet maar wel VOOR elk groepje ... krijgje automatisch:

...groepje1...groepje2...groepje3...groepje4

het enige dat je dan nog moet doen is ... helemaal aan het einde eenmalig toevoegen.

Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
ja ok, maar als het laatste woord nu ook het laatste woord van het text stuk is, dan wil je er geen puntjes achter hebben en bij het begin hetzelfde. Nu heb ik het al opgelost voor het begin, alleen voor het einde is moeilijker, omdat je met een preg replace eerst alle teken weghaalt en dus zal de count() van je words niet kloppen met de count van je stuk text... of zit ik er nu naast ?

Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
RSD schreef op 07 mei 2004 @ 08:41:
ja ok, maar als het laatste woord nu ook het laatste woord van het text stuk is, dan wil je er geen puntjes achter hebben en bij het begin hetzelfde. Nu heb ik het al opgelost voor het begin, alleen voor het einde is moeilijker, omdat je met een preg replace eerst alle teken weghaalt en dus zal de count() van je words niet kloppen met de count van je stuk text... of zit ik er nu naast ?
Je zit er idd naast, de preg_replace (zonder leestekens, zonder hoofdletters) wordt alleen gebruikt om te kunnen matchen. daarna wordt het origineel incl. leestekens en hoofdletters gebruikt voor de output.
Als je zorgt dat je de tekst trimmed voor je begint, kun je de key gewoon gebruiken om te kijken of de laatste woorden getoond zijn.
dus:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$words=explode(' ',trim($text));
$zoekwords=array('amsterdam','politie');
$output='';
$num_words=2;
$lasthit=false;
foreach($words as $key => $word){
    $word=preg_replace('/[\.\,\:\;]$/','',$word); 
    if(in_array(strtolower($word),$zoekwords)){
        if($lasthit===false || $key-$num_words>$lasthit){
            $output.=($key-$num_words <= 0)?'':" ... "; 
            for($i=$num_words;$i>0;$i--){
                $output.=(isset($words[$key-$i]))?' '.$words[$key-$i]:'';
            }
            $output.=' <span class="rood">'.$words[$key].'</span>';
        } else {
            $output.=' <span class="rood">'.$words[$key].'</span>';
        }
        $lasthit=$key;
    } else {
        if($lasthit!==false){
            $output.=($key-$num_words<=$lasthit)?' '.$words[$key-$i]:'';
        }
    }
}
$output.=($key-$num_words>$lasthit)?" ...":'';
echo $output;

Acties:
  • 0 Henk 'm!

Verwijderd

Ik heb zo ergens het idee opgevat dat LIKE toch ietwat traag is, en als je'm dan toch wil gebruiken als

veld1 like '%whatever%' or veld2 like '%whatever%' or veld3 like '%whatever%' or veld4 like '%whatever%' or ...

Dat het mij efficienter lijkt (gebaseerd op puur instinct) om eerst een concat van die veldjes te doen (gescheiden door een of andere sequentie zodat je nog weet in welk veld het was ofzo, ik weet niet) en daar dan eenmaal like op doet. (in standaard SQL is | een concat teken maar ik dacht dat MySQL een functie had voor string concatenation).

Verder klopt het idee wel dat RDBMS's niet geschikt zijn voor searches. Als je kijkt naar Lucene (een jakarta project dat steeds in men gedachten schiet als er over searches gesproken wordt) zie je dat die ook indexen in bestanden genereert en niet werkt met databases.

Acties:
  • 0 Henk 'm!

  • ripexx
  • Registratie: Juli 2002
  • Laatst online: 17:49

ripexx

bibs

Verwijderd schreef op 09 mei 2004 @ 20:54:
Ik heb zo ergens het idee opgevat dat LIKE toch ietwat traag is, en als je'm dan toch wil gebruiken als
Een LIKE wordt pas echt traag als ie geen index kan gebruiken. Wat dus het geval is bij LIKE %iet% queries.
veld1 like '%whatever%' or veld2 like '%whatever%' or veld3 like '%whatever%' or veld4 like '%whatever%' or ...
Dit is dus echt traag, want bij elk veld zal een table scan gedaan moeten worden aangezien er geen index gebruikt kan worden.
Dat het mij efficienter lijkt (gebaseerd op puur instinct) om eerst een concat van die veldjes te doen (gescheiden door een of andere sequentie zodat je nog weet in welk veld het was ofzo, ik weet niet) en daar dan eenmaal like op doet. (in standaard SQL is | een concat teken maar ik dacht dat MySQL een functie had voor string concatenation).
Je kan zolan het gaat om een relatief kleine dataset beter voor de FULLTEXT optie kiezen. Aangezien deze hiervoor gemaakt is en native in MySQL zit. Als je datasets wat groter worden kan je kiezen voor het model waarbij je werkt met een indexer die een wordenlijst bijhoudt en een koppeltabel. Voor de echt grotere sets zal je toch een ander zoektechnologie moeten gebruiken. Zoals bijvoorbeeld xapian zoals dat hier wordt gebruikt. De functie voor string concatenation is CONCAT() :)
Verder klopt het idee wel dat RDBMS's niet geschikt zijn voor searches. Als je kijkt naar Lucene (een jakarta project dat steeds in men gedachten schiet als er over searches gesproken wordt) zie je dat die ook indexen in bestanden genereert en niet werkt met databases.
Helemaal correct maar voor een klein websiteje met niet zo'n hele grote dataset is het best te gebruiken. En voor de grote sites doe je toc aan benchmarking/stresstesten om te kijken waar je problemen zitten.

buit is binnen sukkel

Pagina: 1