Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLite FTS example doesn't work

Tags:

sqlite

fts3

fts4

I've downloaded the latest SQLite 3.7.15.2 shell (Win32) and tried to execute one of the FTS examples exactly as it is written at http://sqlite.org/fts3.html#section_3

-- Virtual table declaration
CREATE VIRTUAL TABLE docs USING fts3();

-- Virtual table data
INSERT INTO docs(docid, content) VALUES(1, 'a database is a software system');
INSERT INTO docs(docid, content) VALUES(2, 'sqlite is a software system');
INSERT INTO docs(docid, content) VALUES(3, 'sqlite is a database');

-- Return the set of documents that contain the term "sqlite", and the
-- term "database". This query will return the document with docid 3 only.
SELECT * FROM docs WHERE docs MATCH 'sqlite AND database';

but in spite of last comment SELECT resulted in empty set. Is it a bug in SQLite or just outdated documentation? (and what is the correct syntax for that?).

What is most important for me is that query

SELECT * FROM docs WHERE docs MATCH '(database OR sqlite) NEAR/5 system';

doesn't work either and that type of queries I need in my app. Is there any other way to write it so it would work?

like image 222
Stan Lagun Avatar asked Feb 02 '13 12:02

Stan Lagun


Video Answer


2 Answers

The example from the documentation uses the enhanced query syntax. Check that PRAGMA compile_options; includes ENABLE_FTS3_PARENTHESIS.

That your NEAR query does not work is not a problem with compilation options:

> SELECT * FROM docs WHERE docs MATCH '(database OR sqlite) NEAR/5 system';
Error: malformed MATCH expression: [(database OR sqlite) NEAR/5 system]

The problem is that, according to the documentation, NEAR does work only with basic search expressions:

A NEAR query is specified by putting the keyword "NEAR" between two phrase, term or prefix queries.

So you have to rewrite your search expression accordingly:

> SELECT * FROM docs WHERE docs MATCH '(database NEAR/5 system) OR (sqlite NEAR/5 system)';
a database is a software system
sqlite is a software system
like image 103
CL. Avatar answered Oct 03 '22 23:10

CL.


I don't know if it is the docs or if it is a bug with SQLite, but here are some alternatives:

For AND queries

Doesn't work:

select * from docs where docs match 'sqlite AND database';

Works (using implied AND):

select * from docs where docs match 'sqlite database';

OR seems to work:

select * from docs where docs match 'sqlite OR database';

For OR + NEAR queries:

Doesn't Work:

SELECT * FROM docs WHERE docs MATCH '(database OR sqlite) NEAR/5 system';

Works:

SELECT * FROM docs WHERE docs MATCH 'database NEAR/5 system'
UNION
SELECT * FROM docs WHERE docs MATCH 'sqlite NEAR/5 system'

EDIT: For the form mentioned in the comments (word11 OR word12 OR word13) NEAR/2 (word21 OR word22 OR word23) NEAR/2 (word31 OR word32 OR word33. This is the best I could do is to put all combinations together with a UNION:

SELECT * FROM docs WHERE docs MATCH 'word11 NEAR/2 word21 NEAR/2 word31'
UNION
SELECT * FROM docs WHERE docs MATCH 'word11 NEAR/2 word22 NEAR/2 word32'
UNION
SELECT * FROM docs WHERE docs MATCH 'word11 NEAR/2 word23 NEAR/2 word33'
UNION
SELECT * FROM docs WHERE docs MATCH 'word12 NEAR/2 word21 NEAR/2 word31'
...

The above of course creates large amounts of SQL. If your words are similar in that only the endings differ, you could use wildcards:

SELECT * FROM docs WHERE docs MATCH 'word1* NEAR/2 word2* NEAR/2 word3*';
like image 34
chue x Avatar answered Oct 03 '22 23:10

chue x