On 6/10/07, Mark Gilbert <[EMAIL PROTECTED]> wrote:
I have just started learning about Full Text search in SQlite, and I
have some questions
Sorry for the delayed response, I just noticed this email waiting for
an answer, and nobody has ...
1) With the Amalgamated Sqlite, I guess to enable FTS I just #define
SQLITE_ENABLE_FTS2 at the start of sqlite3.c
Is there anything else I have to do to switch it on ?
I don't think FTS2 is in the amalgamation. You can either build it
separately and manually hook it in (after sqlite3_open(), call
sqlite3Fts2Init(), like is done in main.c), or you could perhaps
define SQLITE_ENABLE_FTS2, and compile sqlite3.c plus the .c files in
ext/fts2.
2) If I want to do a full text (google style) search across 6 columns
in my database, what is the procedure? Currently I conjor up a
long SQL query with lots of ands and ors. What is to be gained
using FTS ?
CREATE TABLE x USING fts2(a, b, c, d, e, f);
INSERT INTO x (a, b, c, d, e, f) VALUES ('hello', 'world', 'this',
'is', 'a', 'test');
SELECT rowid FROM x WHERE a MATCH 'this'; -- Look for 'this' in column a.
SELECT rowid FROM x WHERE x MATCH 'this'; -- Look for 'this' in any column.
SELECT rowid FROM x WHERE x MATCH 'a:this'; -- Again, only column a.
SELECT rowid FROM x WHERE x MATCH 'this b:that'; -- require 'that'
in column b.
Note the use of a table-named column in the second and later MATCH
calls. This sets the default column specifier for words in the query
to "all".
3) It seems that FTS is basically a special table. Do I have to fill
this table in parallel with my regular columns ? (so its in sync) or
do I recreate the FTS table on every search ? Or do I just fill the
FTS table on its own, and stop using my regular tables altogether ?
Depends entirely on what you're trying to accomplish. FTS is a
separate table which stores TEXT columns, and provides a word-level
index on them. If your current data is just a table of TEXT columns,
you can probably just store it directly in FTS and be done with it.
If it's a mixture of TEXT and non-TEXT, or has other constraints you
might want to have a pair of tables joined on rowid. Sometimes you
want both. Say you want a table where a msgid should be unique, and
other columns should be searchable. You might have something like:
CREATE TABLE a (msgid TEXT PRIMARY KEY);
CREATE TABLE a_fts (subject, body);
You select things using a join on the implicit rowid column (an SQLite
concept which fts abides by):
SELECT msgid, subject, body FROM a JOIN a_fts USING(rowid) WHERE
subject MATCH ?;
To update, make sure you use a transaction to keep things consistent:
BEGIN;
INSERT INTO a (msgid) VALUES (?);
INSERT INTO a_fts (rowid, subject, body) VALUES (last_insert_rowid(), ?, ?);
COMMIT;
BEGIN;
DELETE FROM a_fts WHERE rowid IN (SELECT rowid FROM a WHERE msgid = ?);
DELETE FROM a WHERE msgid = ?;
END;
BEGIN;
UPDATE a_fts SET subject = ? WHERE rowid IN (SELECT rowid FROM a
WHERE msgid = ?);
UPDATE a SET msgid = ? WHERE msgid = ?;
END;
If you wanted msgid to also be searchable, just duplicate it in a_fts.
-scott
-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------