سؤال

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?

هل كانت مفيدة؟

المحلول

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

نصائح أخرى

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*';

According to the documentation (https://www.sqlite.org/fts3.html), parentheses are not supported by default.

Look at part 2. Compiling and Enabling FTS3 and FTS4.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top