[MySQL] Fulltext search werkt niet

Pagina: 1
Acties:

  • NaliXL
  • Registratie: Maart 2002
  • Laatst online: 30-07 19:19
Ik heb gezocht op Google en hier in GOT, maar alle gevonden oplossingen lijken niet op mijn situatie van toepassing te zijn. Het probleem is als volgt. Ik heb deze tabel :
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
+------------------------+------------------+------+-----+---------+----------------+
| Field                  | Type             | Null | Key | Default | Extra          |
+------------------------+------------------+------+-----+---------+----------------+
| domein_test_id         | int(10) unsigned |      | PRI | NULL    | auto_increment |
| domein_test_algemeen   | text             | YES  | MUL | NULL    |                |
| domein_test_name       | varchar(65)      |      |     |         |                |
| domein_test_url        | varchar(200)     | YES  |     | NULL    |                |
| domein_test_noframe    | char(3)          | YES  |     | NULL    |                |
| domein_test_noredirect | char(3)          | YES  |     | NULL    |                |
| domein_test_title      | text             | YES  |     | NULL    |                |
| domein_test_agent      | text             | YES  |     | NULL    |                |
| domein_test_ip         | varchar(16)      | YES  |     | NULL    |                |
| domein_test_extra      | longtext         | YES  |     | NULL    |                |
| domein_test_date       | datetime         | YES  |     | NULL    |                |
+------------------------+------------------+------+-----+---------+----------------+

En de table-index :
code:
1
2
3
4
5
6
7
8
9
10
+---------------+------------+----------------------+--------------+----------------------+-----------+-------------+----------+--------+----------+
| Table         | Non_unique | Key_name             | Seq_in_index | Column_name          | Collation | Cardinality | Sub_part | Packed | Comment  |
+---------------+------------+----------------------+--------------+----------------------+-----------+-------------+----------+--------+----------+
| domein_test_2 |          0 | PRIMARY              |            1 | domein_test_id       | A         |         411 |     NULL | NULL   |          |
| domein_test_2 |          1 | domein_test_algemeen |            1 | domein_test_algemeen | A         |        NULL |        1 | NULL   | FULLTEXT |
| domein_test_2 |          1 | domein_test_algemeen |            2 | domein_test_name     | A         |        NULL |     NULL | NULL   | FULLTEXT |
| domein_test_2 |          1 | domein_test_algemeen |            3 | domein_test_url      | A         |        NULL |     NULL | NULL   | FULLTEXT |
| domein_test_2 |          1 | domein_test_algemeen |            4 | domein_test_title    | A         |        NULL |        1 | NULL   | FULLTEXT |
| domein_test_2 |          1 | domein_test_algemeen |            5 | domein_test_agent    | A         |        NULL |        1 | NULL   | FULLTEXT |
+---------------+------------+----------------------+--------------+----------------------+-----------+-------------+----------+--------+----------+

De tabel is met deze query aangemaakt :
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE TABLE domein_test_2 (
    domein_test_id int UNSIGNED NOT NULL auto_increment PRIMARY KEY,
    domein_test_algemeen text,
    domein_test_name varchar(65) NOT NULL,
    domein_test_url varchar(200),
    domein_test_noframe char(3),
    domein_test_noredirect char(3),
    domein_test_title text,
    domein_test_agent text,
    domein_test_ip varchar(16),
    domein_test_extra longtext,
    domein_test_date datetime,
    FULLTEXT(domein_test_algemeen, domein_test_name, domein_test_url, domein_test_title, domein_test_agent)
);

Ik probeer een query uit te voeren, die er als volgt uitziet :
code:
1
2
3
4
SELECT domein_test_url 
FROM domein_test_2 
WHERE domein_test_name LIKE 'acoperis-etans.' 
ORDER BY (MATCH(domein_test_name) AGAINST('foobar'));

En krijg de welbekende melding "Can't find FULLTEXT index matching the column list". Nou heb ik dus zoals beschreven wel degelijk fulltext indexes op alle betrokken kolommen. Bovendien heb ik een paarhonderd records in m'n tabel, dus ook daar kan het niet aan liggen. Ook een query zoals aangegeven in het voorbeeld, dus zoiets :
code:
1
2
3
SELECT domein_test_url, MATCH(domein_test_name) AGAINST('foobar') 
FROM domein_test_2 
WHERE domein_test_name LIKE 'foobar';

geeft die error.

Wie helpt? Ik zit hier echt met de handen in het haar 8)7 |:( . Zal wel iets heel stoms over het hoofd zien, maar toch...

Genoeg is meer dan veel, en tart den overvloed


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 28-08 12:00

Janoz

Moderator Devschuur®

!litemod

Ik weet het neit zeker, maar ik dacht dat full text search alleen op grote stukken tekst werkte. Waarom gebruik je niet alleen like? Ik neem aan dat in het veld domein_test_name maar 1 'woord' staat. Dan heeft full_text search eigenlijk weinig zin.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • NaliXL
  • Registratie: Maart 2002
  • Laatst online: 30-07 19:19
Janoz schreef op 09 september 2002 @ 10:15:
Ik weet het neit zeker, maar ik dacht dat full text search alleen op grote stukken tekst werkte. Waarom gebruik je niet alleen like? Ik neem aan dat in het veld domein_test_name maar 1 'woord' staat. Dan heeft full_text search eigenlijk weinig zin.
Het punt is dat ik een lijst met domeinnamen heb. Stel ik heb de volgende domeinnamen :

www.piet.com
www.jan.com
www.sintreklaas.com
www.sintreklaas.org
www.sintreklaas.net
www.henk.net
www.henk.org

Nou wil ik alle domeinnamen krijgen van sintreklaas. Dus daarom doe ik een "where domeinnaam like '%sintreklaas%'". (oh, zie dat dat nog niet helemaal klopte in het voorbeeld, maar maakt niet uit). Maar ik wil wel sintreklaas.net bovenaan in de lijst hebben, en niet sintreklaas.com. Daarom is die fulltext-search. Die geeft een relevantie-getal, waardoor als ik het goed hebt sintreklaas.net bovenaan komt als ik daarom vraag.

Genoeg is meer dan veel, en tart den overvloed


  • NaliXL
  • Registratie: Maart 2002
  • Laatst online: 30-07 19:19
Niemand? Sorry, maar ik zit hier te wachten terwijl ik aan het werk hoor te zijn. Wekt niet zo'n goede indruk....

Genoeg is meer dan veel, en tart den overvloed


Verwijderd

waarom wil je per se sinterklaas.net bovenaan hebben staan? behalve de extensie maakt het niet veel uit, je kunt dus gewoon een order by domein asc erin gooien, dan krijg je .com, .net, .org..

  • BlaTieBla
  • Registratie: November 2000
  • Laatst online: 01-09 07:33

BlaTieBla

Vloeken En Raak Schieten

is het niet:

select .....
where (MATCH (Content.ContentBody,Content.ContentTitle) AGAINST ('#Query#'))
order by .....

[sorry, voorbeeld komt uit Coldfusion, maar syntax moet overeenkomen]

leica - zeiss - fuji - apple | PSN = Sh4m1n0


  • NaliXL
  • Registratie: Maart 2002
  • Laatst online: 30-07 19:19
Verwijderd schreef op 09 september 2002 @ 11:27:
waarom wil je per se sinterklaas.net bovenaan hebben staan? behalve de extensie maakt het niet veel uit, je kunt dus gewoon een order by domein asc erin gooien, dan krijg je .com, .net, .org..
Dat zit zo : de domeinnamen in de lijst kunnen een soort wildcards bevatten. Dat kan betekenen dat er alleen het woord sinterklaas staat, zonder extensie o.i.d., samen met een sinterklaas.com en een sinterklaas.org.

Het gaat hier om een forward-script. Ik krijg een URL binnen van een browser (bijvoorbeeld www.sinterklaas.org), en moet dat naar een plek doorsturen die bepaald is in de database. Als ik nou ga matchen op 'sinterklaas.org', dan komt die misschien niet voor, omdat het kan zijn dat er alleen ''sinterklaas' in de DB staat. Daarom doe ik het zo dat 'ie gaat matchen op het woord 'sinterklaas', en dan een voorkeur geeft aan 'sinterklaas.org'.

Genoeg is meer dan veel, en tart den overvloed


  • NaliXL
  • Registratie: Maart 2002
  • Laatst online: 30-07 19:19
BlaTieBla schreef op 09 september 2002 @ 11:27:
is het niet:

select .....
where (MATCH (Content.ContentBody,Content.ContentTitle) AGAINST ('#Query#'))
order by .....

[sorry, voorbeeld komt uit Coldfusion, maar syntax moet overeenkomen]
Uit de MySQL manual kan ik opmaken dat die (Content.ContentBody,Content.ContentTitle) die jij aangeeft slaan op gewone kolommen in de tabel. Dat kan ik o.a. hieruit opmaken :
code:
1
2
3
4
5
6
7
8
9
10
mysql> CREATE TABLE articles (
    ->   id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
    ->   title VARCHAR(200),
    ->   body TEXT,
    ->   FULLTEXT (title,body)
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM articles
    ->          WHERE MATCH (title,body) AGAINST ('database');

Hier worden ook de namen van kolommen opgegeven als argumenten van Match...

Genoeg is meer dan veel, en tart den overvloed


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 28-08 12:00

Janoz

Moderator Devschuur®

!litemod

En waarom zou de full text index daarvoor handig moeten zijn? Dat is me namelijk nog niet helemaal duidelijk. Daarnaast heb ik trouwens ook het vermoeden dat de fulltext index jou ook nog niet helemaal duidelijk is.

FTI werkt mbv de apparte woorden die in een textveld staan. Aangezien het in dit geval telkens maar 1 woord is heeft FTI weinig nut. Mischien kun je sorteren op een andere stringfunctie? (denk aan levensthein distance oid)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

a die fiets...
dan kun je selecteren op
WHERE domein LIKE "%sinterklaas%" ORDER BY domein DESC
wat ie nu doet is alles eruit halen waar sinterklaas in zit, en dan sorteren op domein, maar dan de hoogste value eerst, hierbij zal sinterklaas.org het eerste voorkomen, daarna sinterklaas.net, dan sinterklaas.com en dan sinterklaas... Hij sorteert dus gewoon alfabetisch.
Kijk wel het LIKE stukje na, die weet ik niet 100% zeker, even uit m'n hoofd...

  • BlaTieBla
  • Registratie: November 2000
  • Laatst online: 01-09 07:33

BlaTieBla

Vloeken En Raak Schieten

NaliXL schreef op 09 september 2002 @ 11:38:
[...]

Hier worden ook de namen van kolommen opgegeven als argumenten van Match...
en de vraag is?

leica - zeiss - fuji - apple | PSN = Sh4m1n0


  • JointFillah
  • Registratie: Juli 2000
  • Laatst online: 24-08 07:13

JointFillah

Techno Addict

Eehm nou die query die jij wil doen heb ik ff op eigen table'tje (met een paar honderd records) gedaan....en bij mij werkt het gewoon zonder errors.....in mijn table is echter maar 1 column met FULLTEXT erop.....das het enige verschil dat ik nog kan bedenken...

BTW: Ik weet niet hoe vaak dat forward-script aangeroepen gaat worden, maar denk je niet dat dit een beetje een zware methode is voor een forward-script? Bij iedere request moetie een match gaan doen op een index van een paar honderd records......

~* Peace, Love & XTC *~


Verwijderd

de die fiets slaat op de uitleg over wildcards, even voor de duidelijkheid, kan niet editten, cookies staan uit op school :(

  • NaliXL
  • Registratie: Maart 2002
  • Laatst online: 30-07 19:19
Janoz schreef op 09 september 2002 @ 11:38:
En waarom zou de full text index daarvoor handig moeten zijn? Dat is me namelijk nog niet helemaal duidelijk. Daarnaast heb ik trouwens ook het vermoeden dat de fulltext index jou ook nog niet helemaal duidelijk is.

FTI werkt mbv de apparte woorden die in een textveld staan. Aangezien het in dit geval telkens maar 1 woord is heeft FTI weinig nut. Mischien kun je sorteren op een andere stringfunctie? (denk aan levensthein distance oid)
Fulltext geeft een relevantie. Als ik match op sinterklaas.com, en 'sinterklaas' en 'sinterklaas.com' komen allebei voor, dan zal sinterklaas.com in mijn logica bovenaan komen te staan. Heb ff gezocht op 'levensthein distance' in MySQL manual. Iets dergelijks lijkt niet bekend te zijn. Misschien kan ik die sortering wel in PHP uitvoeren, maar direct vanuit MySQL is natuurlijk wel zo netjes.

Genoeg is meer dan veel, en tart den overvloed


  • NaliXL
  • Registratie: Maart 2002
  • Laatst online: 30-07 19:19
Verwijderd schreef op 09 september 2002 @ 11:40:
a die fiets...
dan kun je selecteren op
WHERE domein LIKE "%sinterklaas%" ORDER BY domein DESC
wat ie nu doet is alles eruit halen waar sinterklaas in zit, en dan sorteren op domein, maar dan de hoogste value eerst, hierbij zal sinterklaas.org het eerste voorkomen, daarna sinterklaas.net, dan sinterklaas.com en dan sinterklaas... Hij sorteert dus gewoon alfabetisch.
Kijk wel het LIKE stukje na, die weet ik niet 100% zeker, even uit m'n hoofd...
Nee, ik moet dus NIET op alphabet hebben. De volgende situatie moet ik hebben :

1. Zoek op resultaten met 'sinterklaas' erin
2. Sorteer die resultaten zo dat als daar ook 'sinterklaas.com' tussen zit, dat die bovenaan komt.

Genoeg is meer dan veel, en tart den overvloed


  • NaliXL
  • Registratie: Maart 2002
  • Laatst online: 30-07 19:19
JointFillah schreef op 09 september 2002 @ 11:42:
BTW: Ik weet niet hoe vaak dat forward-script aangeroepen gaat worden, maar denk je niet dat dit een beetje een zware methode is voor een forward-script? Bij iedere request moetie een match gaan doen op een index van een paar honderd records......
Neehoor, ik filter eerst al een groot deel eruit, meestal blijven er dan maar een paar records over. Daarop word vervolgens een match uitgevoerd.

Genoeg is meer dan veel, en tart den overvloed


  • BlaTieBla
  • Registratie: November 2000
  • Laatst online: 01-09 07:33

BlaTieBla

Vloeken En Raak Schieten

Zo werkt tie bij mij:

<!-- Search version 0.45b -->
....
SELECT Content.ContentID, Content.ContentTitle, Content.ContentDate, Categories.CategoryName, Content.Draft, Content.Private, MATCH (Content.ContentBody,Content.ContentTitle) AGAINST ('#Query#') AS SCORE
FROM Content
LEFT JOIN Categories ON Categories.CatID=Content.Category
WHERE (MATCH (Content.ContentBody,Content.ContentTitle) AGAINST ('#Query#') and (Content.Draft = 'n' AND Content.Private = 'n'))
ORDER BY SCORE DESC

het verdient misschien niet de schoonheidsprijs, maar voorlopig werkt het.

leica - zeiss - fuji - apple | PSN = Sh4m1n0


  • NaliXL
  • Registratie: Maart 2002
  • Laatst online: 30-07 19:19
BlaTieBla schreef op 09 september 2002 @ 11:55:
Zo werkt tie bij mij:

[eenquery]

het verdient misschien niet de schoonheidsprijs, maar voorlopig werkt het.
Huh? Nou zie ik het verband niet helemaal met wat jij daar doet, en wat ik nou doe. Voor de duidelijkheid : ik ken de officiële syntax, en volgens mij heb ik me daar wel aan gehouden, niet?

Genoeg is meer dan veel, en tart den overvloed


  • JointFillah
  • Registratie: Juli 2000
  • Laatst online: 24-08 07:13

JointFillah

Techno Addict

Yupz syntax lijkt niet het probleem....bij mij werkt die query nl wel (zie eerdere post)....

Weet je zeker dat die Fulltext-index goed werkt? Of ben jij niet toevallig net een pechvogel die tegen een bug in een bepaalde versie van MySQL is gevlogen?

~* Peace, Love & XTC *~


  • NaliXL
  • Registratie: Maart 2002
  • Laatst online: 30-07 19:19
Voor de duidelijkheid :
Ik geloof dat de meeste mensen niet helemaal snappen wat ik nou wil. Stel je voor, ik heb de volgende entries in mijn tabel :

1. Sinterklaas.org
2. Sinterklaas.info
3. Sinterklaas.com
4. Sinterklaas

Stel nou dat ik url Sinterklaas.net binnen krijg. Dan staat die dus niet in de database. Daarom ga ik eerst een like uitvoeren met het woord 'Sinterklaas'. Daar zullen dus al deze resultaten uitrollen.
Maar stel nou dat ik winterklaas.com binnen krijg, dan krijg ik dus ook al deze resultaten eruit, met de like query. Het punt is dat ik dan net zo goed 'Sinterklaas.org' of 'Sinterklaas.info' als eerste in de lijst kan binnenkrijgen. Dat wil ik dus voorkomen door een fulltext-search op 'Sinterklaas.com' uit te voeren, zodat die het meeste relevantie krijgt, en dus bovenaan komt te staan als 'ie ertussen zit.

Genoeg is meer dan veel, en tart den overvloed


  • NaliXL
  • Registratie: Maart 2002
  • Laatst online: 30-07 19:19
JointFillah schreef op 09 september 2002 @ 12:10:
Yupz syntax lijkt niet het probleem....bij mij werkt die query nl wel (zie eerdere post)....

Weet je zeker dat die Fulltext-index goed werkt? Of ben jij niet toevallig net een pechvogel die tegen een bug in een bepaalde versie van MySQL is gevlogen?
Hmm, ik begin opeens een donkerbruin vermoeden te krijgen... Met m'n LIKE geef ik aan dat ik maar een beperkt aantal records uit m'n DB wil hebben. Als dat er nou minder dan 3 zijn (wat nogal een het geval zal zijn), dan krijgt die MATCH dus te weinig voor z'n kiezen om relevantie te kunnen geven... Ga het ff uitproberen, hou jullie op de hoogte...

Genoeg is meer dan veel, en tart den overvloed


  • NaliXL
  • Registratie: Maart 2002
  • Laatst online: 30-07 19:19
Nope, ook het bovenstaande is niet het probleem blijkbaar. Zou het dan toch MySQL zijn? De table-index geeft (zoals aangegeven in knip-plak in dit forum) wel degelijk aan dat er fulltext-indexes zijn voor betrokken. Als zo'n bug bekend zou zijn, waar kan ik zoiets dan vinden?

Genoeg is meer dan veel, en tart den overvloed


  • JointFillah
  • Registratie: Juli 2000
  • Laatst online: 24-08 07:13

JointFillah

Techno Addict

Bron: http://www.mysql.com/docu...ual_News.html#News-3.23.x
Changelog mysql-3.23.44
# Fixed core dump when using CREATE ... FULLTEXT keys with other table handlers than MyISAM.
Changelog mysql-3.23.29
# SHOW KEYS now shows whether key is FULLTEXT.
# Fixed bug with several FULLTEXT indexes in one table.
Alleen die laatste lijkt interessant, maar dat gaat over versie 3.23.29....das een best wel oude versie van mysql.....welke versie heb je?

~* Peace, Love & XTC *~

Pagina: 1