[MySQL] zoeken met FULLTEXT index werkt niet

Pagina: 1
Acties:

  • Pelle
  • Registratie: Januari 2001
  • Laatst online: 22:33

Pelle

🚴‍♂️

Topicstarter
Voor kleine tabelletjes met weinig data gebruikte ik als zoek-query vaak iets als dit:
code:
1
2
3
4
SELECT  id,
        naam
FROM      teksten
WHERE    omschrijving LIKE '%blaat%';

Maar nu heb ik een hele zooi grote lappen tekst die doorzocht moeten kunnen worden. Heb de MySQL docs erop nageslagen en heb een tabel met een FULLTEXT index gemaakt op drie velden (titel, tekst en steekwoorden). Die steekwoorden zitten erbij om nog extra woorden op te kunnen geven waar het betreffende record op gevonden kan worden.

Met onderstaand commando heb ik m'n table gedefineerd:
code:
1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE paginas (
     id      INT AUTO_INCREMENT NOT NULL,
     titel      VARCHAR(200),
     tekst      TEXT,
     steekwoorden   TINYTEXT,
     menu        INT,
     categorie  INT,
     locatie      VARCHAR(200),
     PRIMARY KEY    (id),
     FULLTEXT    (titel, tekst, steekwoorden)
);

Hierna heb ik er even 2 testrecords in gegooid (sorry voor de layout verneuking):
code:
1
2
3
4
5
6
7
SELECT * FROM paginas;
+----+---------------------------------+-------------------------------------------------------------------+-----------------------+------+-----------+--------------------------------+
| id | titel                   | tekst                                       | steekwoorden     | menu | categorie | locatie                |
+----+---------------------------------+-------------------------------------------------------------------+-----------------------+------+-----------+--------------------------------+
|  1 | Dit is een titel         | En hier hebben we de tekst. Die bevat wat woorden.            | steekwoord woordsteek |    1 |       1 | direcotry/filename.extensie    |
|  2 | Woei, nog een titel. Echt gaaf. | Zeker wel. Dit is tekst, dat je het even weet. Lorem ipsum. Enzo. | lerp melp       |    1 |      1 | directory2/filename2.extensie2 |
+----+---------------------------------+-------------------------------------------------------------------+-----------------------+------+-----------+--------------------------------+

De MySQL documentatie zegt:
Full-text searching is performed with the MATCH() function.
code:
1
2
mysql> SELECT * FROM articles
    ->      WHERE MATCH (title,body) AGAINST ('database');
Okee, dat ga ik dus toepassen op mijn tabelletje:
code:
1
2
3
4
5
SELECT  id,
        titel,
        MATCH(titel,tekst,steekwoorden) AGAINST('woorden')
FROM      paginas
WHERE    MATCH(titel,tekst,steekwoorden) AGAINST('woorden');

Maar die levert een empty set :(
Na het weghalen van de WHERE-clause, krijg ik dit resultaat:
code:
1
2
3
4
5
6
+----+---------------------------------+----------------------------------------------------+
| id | titel                   | MATCH(titel,tekst,steekwoorden) AGAINST('woorden') |
+----+---------------------------------+----------------------------------------------------+
|  1 | Dit is een titel         |                                 0 |
|  2 | Woei, nog een titel. Echt gaaf. |                                  0 |
+----+---------------------------------+----------------------------------------------------+

Oftewel, hij matched niet, terwijl het eerste record toch echt het woord 'woorden' bevat. Ik doe vast iets heel doms, maar ik zie niet wat :{

Oh ja:
code:
1
mysql  Ver 11.16 Distrib 3.23.49, for redhat-linux-gnu (i386)

Weet niet of dat nog uitmaakt, lijkt me in ieder geval niet.

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Is het niet zo dat je de velden die je matcht ook _moet_ selecten?

edit:
maw
code:
1
2
3
4
5
6
7
SELECT  id,
        titel,
        tekst,         # deze 2
        steekwoorden,     # dus
        MATCH(titel,tekst,steekwoorden) AGAINST('woorden')
FROM      paginas
WHERE    MATCH(titel,tekst,steekwoorden) AGAINST('woorden');

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • Pelle
  • Registratie: Januari 2001
  • Laatst online: 22:33

Pelle

🚴‍♂️

Topicstarter
Lijkt me stug.

Testje:
code:
1
2
3
4
5
6
7
8
mysql> SELECT   id,
    ->       titel,
    ->       tekst,        # deze 2
    ->       steekwoorden,    # dus
    ->       MATCH(titel,tekst,steekwoorden) AGAINST('woorden')
    -> FROM   paginas
    -> WHERE     MATCH(titel,tekst,steekwoorden) AGAINST('woorden');
Empty set (0.00 sec)

Zelfde resultaat :{

  • Pelle
  • Registratie: Januari 2001
  • Laatst online: 22:33

Pelle

🚴‍♂️

Topicstarter
Ok, klap op de vuurpijl:
Ik heb het voorbeeldje uit de MySQL docs even geimplementeerd, en die doet het WEL :?

Ik kan hier echt geen zinnige verklaring voor vinden..
code:
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
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.01 sec)

mysql> INSERT INTO articles VALUES
    ->  (0,'MySQL Tutorial', 'DBMS stands for DataBase ...'),
    ->  (0,'How To Use MySQL Efficiently', 'After you went through a ...'),
    ->  (0,'Optimising MySQL','In this tutorial we will show ...'),
    ->  (0,'1001 MySQL Trick','1. Never run mysqld as root. 2. ...'),
    ->  (0,'MySQL vs. YourSQL', 'In the following database comparison ...'),
    ->  (0,'MySQL Security', 'When configured properly, MySQL ...');
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> select * from articles;
+----+------------------------------+------------------------------------------+
| id | title                | body                       |
+----+------------------------------+------------------------------------------+
|  1 | MySQL Tutorial          | DBMS stands for DataBase ...        |
|  2 | How To Use MySQL Efficiently | After you went through a ...       |
|  3 | Optimising MySQL      | In this tutorial we will show ...      |
|  4 | 1001 MySQL Trick      | 1. Never run mysqld as root. 2. ...  |
|  5 | MySQL vs. YourSQL        | In the following database comparison ... |
|  6 | MySQL Security          | When configured properly, MySQL ...    |
+----+------------------------------+------------------------------------------+
6 rows in set (0.00 sec)

mysql> SELECT * FROM articles
    ->     WHERE MATCH (title,body) AGAINST ('database');
+----+-------------------+------------------------------------------+
| id | title         | body                      |
+----+-------------------+------------------------------------------+
|  5 | MySQL vs. YourSQL | In the following database comparison ... |
|  1 | MySQL Tutorial    | DBMS stands for DataBase ...      |
+----+-------------------+------------------------------------------+
2 rows in set (0.00 sec)

mysql>

  • Banpei
  • Registratie: Juli 2001
  • Laatst online: 15:52
Lees dan de docs ook goed door:
Such a technique works best with large collections (in fact, it was carefully tuned this way). For very small tables, word distribution does not reflect adequately their semantic value, and this model may sometimes produce bizarre results.

mysql> SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('MySQL');
Empty set (0.00 sec)

The search for the word MySQL produces no results in the above example, because that word is present in more than half the rows. As such, it is effectively treated as a stopword (that is, a word with zero semantic value). This is the most desirable behaviour -- a natural language query should not return every second row from a 1GB table.
Meer data toevoegen dus... >:)

Overigens wel een zeeeer interessant onderwerp... Brengt een nieuw licht op mijn ideeen voor zoekfuncties... ;)

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Banpei:
Meer data toevoegen dus... >:)
:O :Z
code:
1
2
3
4
5
6
7
INSERT INTO articles VALUES
    ->  (0,'MySQL Tutorial', 'DBMS stands for DataBase ...'),
    ->  (0,'How To Use MySQL Efficiently', 'After you went through a ...'),
    ->  (0,'Optimising MySQL','In this tutorial we will show ...'),
    ->  (0,'1001 MySQL Trick','1. Never run mysqld as root. 2. ...'),
    ->  (0,'MySQL vs. YourSQL', 'In the following database comparison ...'),
    ->  (0,'MySQL Security', 'When configured properly, MySQL ...');

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • pietje63
  • Registratie: Juli 2001
  • Laatst online: 21:27

pietje63

RTFM

dus mysql zelf kan ook al nadenken :) dat scheelt, alleen maakt dat het (net zoals al die extra ms word functies) soms niet makkelijker, als je niet in de gaten hebt wat er precies gebeurt

De grootste Nederlandstalige database met informatie over computers met zoekfunctie!!


  • Banpei
  • Registratie: Juli 2001
  • Laatst online: 15:52
Op dinsdag 09 juli 2002 15:04 schreef drm het volgende:

[..]

:O :Z
[..]
Ik heb het dus over zijn eerste zoekfunctie... Het tweede werkte dus wel. De eerste dus niet waar ook maar twee records in stonden... |:(

  • Pelle
  • Registratie: Januari 2001
  • Laatst online: 22:33

Pelle

🚴‍♂️

Topicstarter
* Pelle heeft even gekeken, en inderdaad, bizarre resultaten:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mysql> select * from paginas;
+----+-------------------------------------------+-------------------------------------------------------------------+
| id | titel                         | tekst                                         |
+----+-------------------------------------------+-------------------------------------------------------------------+
|  1 | Dit is een titel               | En hier hebben we de tekst. Die bevat wat woorden.          |
|  2 | Woei, nog een titel. Echt gaaf.       | Zeker wel. Dit is tekst, dat je het even weet. Lorem ipsum. Enzo. |
|  3 | waarom doet niet? ik weet nie hoor.. blab | blaas ;lkj sdkd  dka  dsfasd fasdf melp lerp zaag slurp       |
|  4 | sjaak de bever is gekomen             | om vrede te sluiten met de grote mens                     |
|  5 | zwaaiend met hun witte vlaggetjes       | maken zij een feestelijke indruk                       |
+----+-------------------------------------------+-------------------------------------------------------------------+
5 rows in set (0.00 sec)

mysql> SELECT * FROM paginas
    ->     WHERE MATCH (titel,tekst) AGAINST ('tekst');
+----+---------------------------------+-------------------------------------------------------------------+
| id | titel                   | tekst                                       |
+----+---------------------------------+-------------------------------------------------------------------+
|  1 | Dit is een titel         | En hier hebben we de tekst. Die bevat wat woorden.            |
|  2 | Woei, nog een titel. Echt gaaf. | Zeker wel. Dit is tekst, dat je het even weet. Lorem ipsum. Enzo. |
+----+---------------------------------+-------------------------------------------------------------------+
2 rows in set (0.00 sec)

He, cool, hij werkt :)
Meer data erin gooien werkt dus.. beetje jammer is dat, ik ga er pas data ingooien als ik weet dat het werkt.. beetje een vieze cirkel :D

Maare, bedankt voor de tip, ik kan weer vooruit :)

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Banpei:
Ik heb het dus over zijn eerste zoekfunctie... Het tweede werkte dus wel. De eerste dus niet waar ook maar twee records in stonden... |:(
Dat was dus exact het verwarrende eraan, he :* Je zegt "meer data toevoegen" maar bedoelt "meer records toevoegen".

zijn duidelijk niet dezelfde dingen.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz

Pagina: 1