[MYSQL] Sorteren op belangrijkheid?

Pagina: 1
Acties:
  • 302 views sinds 30-01-2008
  • Reageer

  • Morphine
  • Registratie: Februari 2002
  • Laatst online: 25-01 20:38
Hallo heren,

Ik ben bezig op het moment met een zoekmachientje.
Ik zal een kleine case voorschrijven waarvan ik zou willen dat de volgorde op een andere manier eruit komt (wellicht moet ik na het uitvoeren van de query nog dingen uitvoeren om de volgorde te manipuleren als het niet anders kan hoor!)

Zoekstring: Making a pond.

De query
code:
1
2
3
4
5
6
SELECT * from site_paginas t
WHERE t.menu_naam LIKE '%making%' 
OR  t.menu_naam LIKE '%pond%' 
OR  t.menu_naam = 'making a pond'  
AND t.hidden != 'Y'
order by menu_naam LIMIT 0,40
Zoals je ziet wordt er op dit moment alleen binnen het veld menu_naam gezocht (er worden uiteindelijk meerde velden doorzocht, maar heb het zo simpel mogelijk proberen te houden). Er wordt op de drie losse velden gezocht, en de op gehele string aan elkaar.

Nu wil ik dat, als de gehele string voorkomt, dat deze natuurlijk hoogste prioriteit heeft en als eerste wordt weergegeven in de resultaten, daarna pas de losse woorden.

Uitvoer wordt:
> Air Wells & Dew Ponds
> Aromatic Plants for the Pond
> Candle-making
> Cheese Making
> Garden Food Pond
> Maintaining your Pond
> Making a Pond
> Making Biodiesel Fuel at Home
> Making Chicken Feed
> Making Herbal Remedies

Hoe ga ik dit oplossen (ik denk dat ik wellicht met wat haken moet gaan werken hier en daar, maargoed ik zit al zo lang te proberen dat ik even geen weg meer zie).

Mijn dank alvast _/-\o_

  • TheBorg
  • Registratie: November 2002
  • Laatst online: 11:01

TheBorg

Resistance is futile.

Google eens naar fulltext search, dan kun je de resultaten sorteren best match.

  • Morphine
  • Registratie: Februari 2002
  • Laatst online: 25-01 20:38
Maar betekent het nu dat ik heel die OR constructie met where like '%keyword%' niet meer nodig heb en gewoon MATCH against kan gebruiken??? Dat is wel heel erg mooi namelijk en scheelt een lap met code :-)

Maargoed ik heb diverse FULLTEXT nu toegevoegd in de tabel en de query aangepast:
code:
1
2
3
4
        SELECT * from site_paginas t
 WHERE  MATCH(menu_naam) AGAINST ('making a pond')
 AND t.hidden != 'Y'
 LIMIT 0,40


___________

Ik merkte overigens als ik meerdere fields nu toevoeg in de MATCH(menu_naam,naam,content)
dat de volgorde nu weer een beetje door elkaar raakt :(
code:
1
2
3
    SELECT * from site_paginas t
 WHERE  MATCH(menu_naam,naam,content) AGAINST ('making a pond') AND t.hidden != 'Y'
 LIMIT 0,40


Resultaten zijn nu:
> Garden Food Pond (hier komen de woorden in de content voor door elkaar)
> Managing Sport Fish Populations in Farm Ponds (hier komt alleen pond in voor)
> Pond Building
> Winter Pond (part two)
> Making a Pond (deze moet toch gewoon als 1e :/ )
> Gathering Water Without Electricity
+ nog een paar 100 :)

[ Voor 62% gewijzigd door Morphine op 29-04-2006 20:37 ]


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 09-12-2025
De juiste syntax is zo:
SQL:
1
2
3
4
5
SELECT *, MATCH(menu_naam,naam,content) AGAINST ('making a pond') AS weight
FROM site_paginas t
WHERE MATCH(menu_naam,naam,content) AGAINST ('making a pond') AND t.hidden != 'Y'
ORDER BY weight DESC
LIMIT 0,40

Dat sorteert hij pas echt op overeenkomst.

Noushka's Magnificent Dream | Unity


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Buiten de match-against oplossingen:
code:
1
2
3
4
5
6
7
SELECT * from site_paginas t
WHERE t.menu_naam LIKE '%making%' 
OR  t.menu_naam LIKE '%pond%' 
OR  t.menu_naam = 'making a pond'  
AND t.hidden != 'Y'
order by menu_naam = 'making a pond' DESC, menu_naam 
LIMIT 0,40


Oftewel, bepaal een boolean-expressie voor 'menu_naam = ' en sorteer daar omgekeerd op (zodat true bovenaan komt).

  • Morphine
  • Registratie: Februari 2002
  • Laatst online: 25-01 20:38
Michali schreef op zaterdag 29 april 2006 @ 21:10:
De juiste syntax is zo:
SQL:
1
2
3
4
5
SELECT *, MATCH(menu_naam,naam,content) AGAINST ('making a pond') AS weight
FROM site_paginas t
WHERE MATCH(menu_naam,naam,content) AGAINST ('making a pond') AND t.hidden != 'Y'
ORDER BY weight DESC
LIMIT 0,40

Dat sorteert hij pas echt op overeenkomst.
Deze oplossing geeft dezelfde rij oplossingen als ik al had:
> Garden Food Pond
> Managing Sport Fish Populations in Farm Ponds
> Pond Building
> Winter Pond (part two)
> Making a Pond
> Gathering Water Without Electricity
etc + meer
ACM schreef op zaterdag 29 april 2006 @ 22:47:
Buiten de match-against oplossingen:
code:
1
2
3
4
5
6
7
SELECT * from site_paginas t
WHERE t.menu_naam LIKE '%making%' 
OR  t.menu_naam LIKE '%pond%' 
OR  t.menu_naam = 'making a pond'  
AND t.hidden != 'Y'
order by menu_naam = 'making a pond' DESC, menu_naam 
LIMIT 0,40


Oftewel, bepaal een boolean-expressie voor 'menu_naam = ' en sorteer daar omgekeerd op (zodat true bovenaan komt).
Maar deze doetet wel :) (klinkt ook wellicht wat logischer?).

Overigens, (nu dwaal ik wellicht af van het onderwerp zonder te googlen hoor) weet iemand een techniek om een klein stukje tekst uit de content te halen waar het zoekwoord in voorkomt (ala google)

[ Voor 23% gewijzigd door Morphine op 01-05-2006 09:35 ]


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 09-12-2025
Ik zou de indices van de gezochte woorden opzoeken, en daarvan, afhankelijk van hoeveel woorden het zijn en hoe vaak ze er in voorkomen, dan gedeelten van de omliggende tekst inclusief het woord zelf laten zien. Dat doe je dan door de index van het woord in de tekst te zoeken, en dan een substring te nemen vanaf die index min een aantal tekens en tot die index plus een aantal tekens. Dan zet je er bijvoorbeeld '...' voor en na om aan te geven dat het maar een gedeelte is. Alle samples combineer je dan op de juiste wijze en dat laat je zien.

De oplossing van ACM sorteert alleen niet op relevantie, maar zorgt er wel voor dat degene waarin de volledig string voorkomt bovenaan komt. Je kunt beide oplossingen ook combineren als je wilt. Misschien werkt het beter als je die full text search alleen op menu_naam uitvoert.

[ Voor 22% gewijzigd door Michali op 01-05-2006 10:36 ]

Noushka's Magnificent Dream | Unity


  • Morphine
  • Registratie: Februari 2002
  • Laatst online: 25-01 20:38
klopt ik merkte het, alleen een fulltext op menu_naam zorgt idd voor meer belangrijkheid in de naam van de content :)

nu kwam ik wel achter een foutje in mn (nu nog oude) query :(
code:
1
2
3
4
5
6
7
SELECT * from site_paginas t
 WHERE t.menu_naam LIKE '%galerij%' 
 OR t.menu_naam = ('galerij') OR  t.naam LIKE '%galerij%' 
 OR t.naam = ('galerij') OR  t.content LIKE '%galerij%' 
 OR t.content = ('galerij')
 AND t.hidden != 'Y' and t.lid='2' 
order by menu_naam = 'galerij' DESC, menu_naam  LIMIT 0,30


Het AND t.hidden != 'Y' and t.lid='2' werkt niet! Waarschijnlijk doordat het direct na or.tcontent='zoekstring' komt.

Hoe zorg ik dat t.hidden != y and t.lid='2' altijd moeten voldoen? (haken???)

[ Voor 38% gewijzigd door Morphine op 01-05-2006 12:41 ]


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 09-12-2025
Je werkt hem nu weg met een OR. Je moet om alle OR vergelijkingen haken zetten:
SQL:
1
2
3
4
5
6
7
8
SELECT * from site_paginas t
 WHERE (
 t.menu_naam LIKE '%galerij%' 
 OR t.menu_naam = ('galerij') OR  t.naam LIKE '%galerij%' 
 OR t.naam = ('galerij') OR  t.content LIKE '%galerij%' 
 OR t.content = ('galerij')
) AND t.hidden != 'Y' and t.lid='2' 
order by menu_naam = 'galerij' DESC, menu_naam  LIMIT 0,30

Nu moet een van de opties in die haken waar zijn wil de rij geselecteerd worden.

Als je maar uit 1 tabel selecteert, dan hoef je de tabelnaam (of alias) niet op te geven, trouwens.

Noushka's Magnificent Dream | Unity


Verwijderd

Bovendien is dit ook een beetje overbodig:
SQL:
1
t.menu_naam LIKE '%galerij%'  OR t.menu_naam = ('galerij')

Als menu_naam 'galerij' is, voldoet 'ie ook al aan de LIKE vergelijking.
Als je 't andersom zou testen, dus eerst alle '=' vergelijking en daarna de 'like', was 't misschien nog de moeite waard geweest: bij '=' vergelijkingen kan je database nuttig gebruik maken van indexen (indien aanwezig), maar bij 'like' vergelijkingen die beginnen met '%' is dat onmogelijk, en moet 'ie dus de hele tabel door.
Full text search kan daar wel wat in verbeteren, maar heeft een hoop overhead die je meestal toch niet nodig hebt. In jouw geval is het content veld misschien wel een geschikte kandidaat voor full text search.

Verwijderd

zou geen logica in de database laag proppen, misschien lucene gebruiken ?

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Je kunt ook het sorteringsalgoritme van MySQL fulltext implementeren in PHP, en daarin de beperkingen van de MySQL implementatie (zoals het niet geven van resultaten bij een resulset die > 50% van de zoekset is, meegecompileerde stopwords, meegecompileerde minimale lengte vd zoekterm, beperkte mogelijkheid voor wildcards etc) opheffen. Waar het op neerkomt is dit:

code:
1
2
3
4
5
6
7
8
9
weight = (log(dtf)+1)/sumdtf * U/(1+0.0115*U) * log((N-nf)/nf)

waar:

dtf     is the number of times the term appears in the document
sumdtf  is the sum of (log(dtf)+1)'s for all terms in the same document
U       is the number of Unique terms in the document
N       is the total number of documents
nf      is the number of documents that contain the term


Bij mijn implementatie heb je per tabel 3 extra velden: sumdtf, norm_pivot (=U/(1 + 0.0115 * U)) en ft, welke een textveld is met daarin alle relevante woorden uit alle textmembers van het record. Het leeuwedeel van het rekenwerk zit em bij het INSERTEN of UPDATEN van een los record, het zoeken zelf gaat daarna bijna net zo snel of in sommige gevallen sneller dan met de ingebakken fulltext-search. En de resultaten zijn veel beter.

http://dev.mysql.com/doc/internals/en/full-text-search.html

[ Voor 6% gewijzigd door Genoil op 01-05-2006 17:12 ]


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Verwijderd schreef op maandag 01 mei 2006 @ 15:18:
zou geen logica in de database laag proppen, misschien lucene gebruiken ?
En dan stop je het in een andere database? Een database is om in gegevens te zoeken (lucene is er dus ook een), dat doet ie nu toch met mysql? Dat er databases zijn die bij met name grote hoeveelheden data beter werken om documenten bij zoekwoordne te vinden is een ander verhaal.
Genoil schreef op maandag 01 mei 2006 @ 17:07:
Bij mijn implementatie heb je per tabel 3 extra velden: sumdtf, norm_pivot (=U/(1 + 0.0115 * U)) en ft, welke een textveld is met daarin alle relevante woorden uit alle textmembers van het record. Het leeuwedeel van het rekenwerk zit em bij het INSERTEN of UPDATEN van een los record, het zoeken zelf gaat daarna bijna net zo snel of in sommige gevallen sneller dan met de ingebakken fulltext-search. En de resultaten zijn veel beter.
En hoe zoek je precies in dat textveld? Eerlijk gezegd kan ik me niet voorstellen dat dat net zo snel of sneller werkt dan een FTI-oplossing voor grotere hoeveelheden data.

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
ACM schreef op maandag 01 mei 2006 @ 18:58:

[...]

En hoe zoek je precies in dat textveld? Eerlijk gezegd kan ik me niet voorstellen dat dat net zo snel of sneller werkt dan een FTI-oplossing voor grotere hoeveelheden data.
Ik heb de bijbel gebruikt als test, met 30.000 records, 1 voor elke verse. Ik probeer even een testversie daarvan aan de praat te krijgen om te zien hoe snel het ook alweer was. Is al even geleden dat ik er iets concreets mee gedaan hebt. Gebruik em wel altijd standaard en ik heb nog geen klachten gehad :)

Het zoeken in de tekst gaat met LIKE. Ik heb het bepalen van het gewicht zelf uitgebreid met een voorkeur voor losstaande termen, en mindere waarde voor termen die een deel uitmaken van een groeter woord. De kolom waarin daadwerkelijk wordt gezocht bestaat uit woorden die (per taal) gefilterd is met een common_words bestand. Voor die kolom worden een aantal constanten gedefineerd op basis van de woordzaaing, en die worden in die hocuspocus formule gecombineerd met een aantal dynamische parameters op basis van de (eveneens gefilterde) zoekopdracht.

Voor elke kolom waar een of meerdere zoektermen worden gevonden wordt in PHP een gewicht bepaald die de uitkomst is van die formule, die ik wel eens half begrepen heb maar nu even kwijt ben ;). Die worden in PHP gesorteerd en dat is het eigenlijk wel...

Ik moet eigenlijk nog een regel voor exact matches toevoegen maar daar ben ik nog niet aan toekgekomen...

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Genoil schreef op maandag 01 mei 2006 @ 19:36:
Ik heb de bijbel gebruikt als test, met 30.000 records, 1 voor elke verse.
Hoewel het een heel dik boek is, is dat imho nog een vrij normale dataset. Als ik hem vergelijk met waar wij naar echte FTI-toepassingen uitweken (m.n. het forum) is het zelfs maar een kleintje.
Met zo'n dataset geloof ik wel dat LIKE nog behoorlijk vlot is.
Ik probeer even een testversie daarvan aan de praat te krijgen om te zien hoe snel het ook alweer was. Is al even geleden dat ik er iets concreets mee gedaan hebt. Gebruik em wel altijd standaard en ik heb nog geen klachten gehad :)

Het zoeken in de tekst gaat met LIKE. Ik heb het bepalen van het gewicht zelf uitgebreid met een voorkeur voor losstaande termen, en mindere waarde voor termen die een deel uitmaken van een groeter woord.
Mijn ruwe schatting is dat het tot zo'n 100k kleine records het nog best aardig met een LIKE te doen is.
De kolom waarin daadwerkelijk wordt gezocht bestaat uit woorden die (per taal) gefilterd is met een common_words bestand.
En dat maakt het natuurlijk nog wat beter, dat je de te doorzoeken tekst nog wat verder "comprimeert".
Voor elke kolom waar een of meerdere zoektermen worden gevonden wordt in PHP een gewicht bepaald die de uitkomst is van die formule, die ik wel eens half begrepen heb maar nu even kwijt ben ;). Die worden in PHP gesorteerd en dat is het eigenlijk wel...
Nadeel is dat dit er voor kan zorgen dat er honderden of zelfs duizenden records in je geheugen geladen worden.

Al met al denk ik dat je oplossing een leuke, maar vrij bewerkelijke, variant op de LIKE is en niet echt als volwaardige vervanger voor FTI gezien kan worden. Zeker op het gebied van schaling loop je waarschijnlijk een stuk sneller tegen de lamp, want jouw oplossing is voor zover ik kan inschatten nu niet in staat efficient gebruik te maken van indexen.
Overigens lopen eigen document-term modellen in SQL ook al gauw tegen combinatorische explosies aan als je de eenvoudigere, maar een beetje naive aanpak neemt.

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
hij doet et:

http://www.meneer.net/biible

Onderaan de resultaten staat de processing tijd van een query. Je kunt ook vergelijken met de standaard musql fulltext, door &m=fulltext toe te voegen in de URL, (maar dan krijg je wel alle hits op 1 pagina). MySQL fulltext is wel sneller, maar vindt niet alles.

  • T-MOB
  • Registratie: Maart 2001
  • Nu online
offtopic:
Als ie niets vind gaat er nog wat mis met de foreach op regel 88

Regeren is vooruitschuiven


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
T-MOB schreef op maandag 01 mei 2006 @ 20:56:
offtopic:
Als ie niets vind gaat er nog wat mis met de foreach op regel 88
JA! :P

  • pistole
  • Registratie: Juli 2000
  • Laatst online: 11:55

pistole

Frutter

en zoeken op ' (apostrophe) is ook leuk ;)

[ Voor 27% gewijzigd door pistole op 01-05-2006 21:03 ]

Ik frut, dus ik epibreer


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
het is een demo om dingen te vinden, niet om dingen NIET te vinden ;)

  • Morphine
  • Registratie: Februari 2002
  • Laatst online: 25-01 20:38
Genoil schreef op maandag 01 mei 2006 @ 21:20:
het is een demo om dingen te vinden, niet om dingen NIET te vinden ;)
zeg en hoe heb jij het nu voor elkaar gekregen dat mooie stukje tekst onder het resultaat weer te geven?

(al gaat dit: http://www.meneer.net/bii...p?q=jesus&o=book&f=1&t=10, ook niet helemaal lekker ;))

[ Voor 17% gewijzigd door Morphine op 05-05-2006 10:55 ]


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Morphine schreef op vrijdag 05 mei 2006 @ 10:51:
[...]


zeg en hoe heb jij het nu voor elkaar gekregen dat mooie stukje tekst onder het resultaat weer te geven?

(al gaat dit: http://www.meneer.net/bii...p?q=jesus&o=book&f=1&t=10, ook niet helemaal lekker ;))
Wat bedoel je precies? Dat tabelletje met tijden? Of de gehighlighte text bij het resultaat?

  • Morphine
  • Registratie: Februari 2002
  • Laatst online: 25-01 20:38
Genoil schreef op vrijdag 05 mei 2006 @ 11:00:
[...]


Wat bedoel je precies? Dat tabelletje met tijden? Of de gehighlighte text bij het resultaat?
de highlighted text :), zoiets wil ik eigenlijk ook wel :]

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Aangezien er geen HTML in de bijbel staat, heb ik een vrij simpele gebruikt in "biible":

PHP:
1
2
3
4
5
6
7
    function setQuery($query) {
        $this->query = $query;
        $words = explode(" ", $query);
        foreach($words as $word) {
            $this->pregWords[] = "/".$word."/i";
        }
    }


PHP:
1
2
3
    function highlight($text, $tag = "strong") {
        return preg_replace($this->pregWords, "<".$tag.">$0</".$tag.">", $text);
    }


Die werkt alleen niet lekker met html content, wanneer de zoekterm bijvoorbeeld een tag of attribuut is of voorkomt in de waarde van een attribuut. Ik gebruik nu deze Javascript functies die ik ergesn opgenort heb:

JavaScript:
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
var Search = new function() {
    
}

Search.wordHighlight =  function(aSourceObject, aWords){
    //Extract HTML Tags
    regexp=/<[^<>]*>/ig;
    vHTMLArray = aSourceObject.innerHTML.match(regexp);
    //Replace HTML tags
    vStrippedHTML = aSourceObject.innerHTML.replace(regexp,"$!$");
        
    //Replace search words
    regexp= new RegExp ("(" + aWords + ")", "gi");
    vTemp = vStrippedHTML.replace(regexp,'<span class="highlight">$1</span>');
    
    //Reinsert HTML
    for(i=0;vTemp.indexOf("$!$") > -1;i++){
        vTemp = vTemp.replace("$!$", vHTMLArray[i]);
    }
    //Display Result
    aSourceObject.innerHTML = vTemp;
}

Search.removeHighlight = function(aSourceObject){
    regexp=/(<span class\=\"highlight\">)([^<>]*)(<\/span>)/ig;
    aSourceObject.innerHTML = aSourceObject.innerHTML.replace(regexp, "$2");
}

[ Voor 13% gewijzigd door Genoil op 05-05-2006 11:12 ]


  • Morphine
  • Registratie: Februari 2002
  • Laatst online: 25-01 20:38
uhm.. :o erg mooi maar betekent dat ik heel de content per zoekresultaat naar dat javascriptje moet gooien, vervolgens geeft die mij een goede stuk tekst terug die ik dan als highlighted tekst kan weergeven :??

[ Voor 5% gewijzigd door Morphine op 05-05-2006 11:18 ]


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Morphine schreef op vrijdag 05 mei 2006 @ 11:18:
uhm.. :o erg mooi maar betekent dat ik heel de content per zoekresultaat naar dat javascriptje moet gooien, vervolgens geeft die mij een goede stuk tekst terug die ik dan als highlighted tekst kan weergeven :??
Nee idd...ik ben toevallig net bezig met wat programmeerwerk aan dat zoekscript, en kom net toevallig tegen waar jij natuurlijk echt naar op zoek bent :)

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
// todo: rewrite this so that fragments don't overlap.
    function getHighlightedFragments($text, $maxLength = 128, $tag = "strong") {
        $uwords     = array_unique($this->words);

        $nFragments = sizeof($uwords);
        $fragLength = $maxLength / $nFragments; 
        $wordPos    = array();
        $fragments  = array();      
        foreach($uwords as $n => $word) {
            $pos     = strpos(strtolower($text), $word);
            $dotsEnd = true;
            if($pos !== null) {
                $pad        = ($fragLength - strlen($word)) / 2;
                $start      = $pos - $pad >= 0 ? $pos - $pad : 0;
                if($pos + $pad > strlen($text)) {
                    $start   = strlen($text) - $fragLength > 0 ? strlen($text) - $fragLength : 0;               
                    $dotsEnd = false;
                } 
                $fragment = substr($text, $start, $fragLength);
                if($start > 0 && $n == 0) $fragment = "...".$fragment;
                if($dotsEnd)  $fragment.= "...";
                $fragments[] = $fragment;
            }
        }

        $text = $this->highlight(implode("", $fragments));
        return $text;
    }

  • Morphine
  • Registratie: Februari 2002
  • Laatst online: 25-01 20:38
Genoil schreef op vrijdag 05 mei 2006 @ 11:21:
[...]


Nee idd...ik ben toevallig net bezig met wat programmeerwerk aan dat zoekscript, en kom net toevallig tegen waar jij natuurlijk echt naar op zoek bent :)

PHP:
1
...
Denk dat je dit beter op SQL niveau kan opvangen? Of wordt dat lastig met meerdere fragmenten zoals de functie hierboven (denk ik) wel erg mooi oplost?

Geloof dat die functie ook niet goed omgaat met HTML tags :(

[ Voor 62% gewijzigd door Morphine op 05-05-2006 11:29 ]


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Maj ik zit ff te kijken...en dat stuk code wat ik net post zit helemaal niet in die biible demo :). Ik kan dit iig niet op SQL niveau opvangen, ongeacht of ik m'n eigen fulltext of mysql fulltext gebruik.

Mja zit wat in dattie wel eens herschreven zou mogen worden met gestripte html :). Die functie zou wel raar gaan doen bij zoeken op get woord "strong" in een HTML tekst die zowel het woord als de tag bevat...

Oh wacht ik zie dat ik dat nu standaard omzeil met
PHP:
1
FtLikeSearch::getHighlightedFragments(strip_tags($result->body))


En de $this->highligh is in de latere revisies van m'n class al lang weg uit dat stukje code en vervangen door die JS highlight

[ Voor 64% gewijzigd door Genoil op 05-05-2006 11:42 ]


  • Morphine
  • Registratie: Februari 2002
  • Laatst online: 25-01 20:38
haha ik volg er helemaal niks meer van.. ik ga wel is gewoon googlen naar een $body naar $fragments converter :-P

  • Morphine
  • Registratie: Februari 2002
  • Laatst online: 25-01 20:38
Michali schreef op maandag 01 mei 2006 @ 10:33:
Ik zou de indices van de gezochte woorden opzoeken, en daarvan, afhankelijk van hoeveel woorden het zijn en hoe vaak ze er in voorkomen, dan gedeelten van de omliggende tekst inclusief het woord zelf laten zien. Dat doe je dan door de index van het woord in de tekst te zoeken, en dan een substring te nemen vanaf die index min een aantal tekens en tot die index plus een aantal tekens. Dan zet je er bijvoorbeeld '...' voor en na om aan te geven dat het maar een gedeelte is. Alle samples combineer je dan op de juiste wijze en dat laat je zien.
...
Ik ben bezig om dit te maken, maar heb ik hierbij de fulltext functie nodig? Heb overigens weinig idee hoe ik dit verder aan moet pakken.

Enig idee met welke functie ik de index kan vinden van het woord binnen de content? Als ik die heb dan is het substr een eitje verder denk ik. De indice vinden (whatever that may be :)), en ook nog tellen hoeveel worden het zijn en dan ook nog de rest van de keywords checken (ik probeer het eerst ffies met de eerste) zal wat lastiger worden, maargoed ik moet ergens beginnen.

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 09-12-2025
Die heb je in princiepe niet nodig. Ik zou dat ook met php zelf doen (als er geen methode is in mysql om dat voor je te laten doen, maar dat weet ik niet).

Je kunt daar strpos of stripos (voor case insensitive) voor gebruiken, maar die halen echter alleen de eeste index op. Je kunt ze zo allemaal ophalen:
PHP:
1
2
3
$indices = array();
$pos = -1;
while ( ( $pos = stripos($text, $searchWord, $pos + 1) ) !== false ) $indices[] = $pos;

Waarbij $text dan de tekst is waarin je wilt zoeken en $searchWord één van de zoek woorden is. (Die kun je overigens met explode() mooi splitsen.)

Noushka's Magnificent Dream | Unity


  • Morphine
  • Registratie: Februari 2002
  • Laatst online: 25-01 20:38
Michali schreef op zondag 07 mei 2006 @ 18:10:
Die heb je in princiepe niet nodig. Ik zou dat ook met php zelf doen (als er geen methode is in mysql om dat voor je te laten doen, maar dat weet ik niet).

Je kunt daar strpos of stripos (voor case insensitive) voor gebruiken, maar die halen echter alleen de eeste index op. Je kunt ze zo allemaal ophalen:
PHP:
1
2
3
$indices = array();
$pos = -1;
while ( ( $pos = stripos($text, $searchWord, $pos + 1) ) !== false ) $indices[] = $pos;

Waarbij $text dan de tekst is waarin je wilt zoeken en $searchWord één van de zoek woorden is. (Die kun je overigens met explode() mooi splitsen.)
Hmm das zonde, stripos is er alleen sinds versie 5.. kan ik die functie nie ergens copy pasten? Of gaat dan nie werken?
Pagina: 1