Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use FULL-TEXT SEARCH in H2 Database?

Consider the following example

CREATE ALIAS IF NOT EXISTS FT_INIT FOR "org.h2.fulltext.FullText.init";
CALL FT_INIT();
DROP TABLE IF EXISTS TEST;
CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR);
INSERT INTO TEST VALUES(1, 'Hello World');
CALL FT_CREATE_INDEX('PUBLIC', 'TEST', NULL);

and i have executed the following query

SELECT * FROM FT_SEARCH('Hello', 0, 0);

But this query is returning "PUBLIC"."TEST" WHERE "ID"=1 .

  1. Do i have to again execute this "PUBLIC"."TEST" WHERE "ID"=1 to get the record containing 'Hello' word ?
  2. What is the query to search all records with 'ell' word in them from the FT_Search. such as like %ell% in H2 Native Full-Text Search
like image 632
Vivek Avatar asked Jul 10 '11 14:07

Vivek


2 Answers

  1. Yes, each row in a query using FT_SEARCH represents a schema-table-row where one of the key words was found. The search is case insensitive, and the text parameter to FT_SEARCH may include more than one word. For example,

    DELETE FROM TEST;
    INSERT INTO TEST VALUES(1, 'Hello World');
    INSERT INTO TEST VALUES(2, 'Goodbye World');
    INSERT INTO TEST VALUES(3, 'Hello Goodbye');
    CALL FT_REINDEX();
    SELECT * FROM FT_SEARCH('hello goodbye', 0, 0);
    

    returns only row three:

    QUERY                           SCORE  
    "PUBLIC"."TEST" WHERE "ID"=3    1.0
    

    Also note that FT_SEARCH_DATA may be used to retrieve the data itself. For example,

    SELECT T.* FROM FT_SEARCH_DATA('hello', 0, 0) FT, TEST T
    WHERE FT.TABLE='TEST' AND T.ID=FT.KEYS[0];
    

    returns both rows containing the keyword:

    ID   NAME  
    1    Hello World
    3    Hello Goodbye
    
  2. Apache Lucene supports wildcard searches, although leading wildcards (e.g. *ell) tend to be expensive.

like image 102
trashgod Avatar answered Oct 31 '22 12:10

trashgod


Do i have to again execute this "PUBLIC"."TEST" WHERE "ID"=1 to get the record containing 'Hello' word ?

Yes, except if you use a join as described by trashgod. The reason is: usually rows are much larger than just two words. For example, a row contains a CLOB with a document. If the result of the fulltext search would contain the data, then fulltext search would be much slower.

What is the query to search all records with 'ell' word in them from the FT_Search. such as like %ell% in H2 Native Full-Text Search

The native fulltext search can't do that directly. The reason is: fulltext search only indexes whole words. (By the way: does Google support searches if you only know a part of a word? Apache Lucene does support it) Actually, for H2, there would be a way: first, search the words table (FT.WORDS) for matches, and then use a regular search.

like image 43
Thomas Mueller Avatar answered Oct 31 '22 13:10

Thomas Mueller