Пример SQLite FTS не работает

Я скачал последнюю оболочку SQLite 3.7.15.2 (Win32) и попытался выполнить один из примеров FTS точно так, как написано на http://sqlite.org/fts3.html

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

но, несмотря на последний комментарий, SELECT привел к пустому набору. Это ошибка в SQLite или просто устаревшая документация? (и какой правильный синтаксис для этого?).

Для меня важнее всего этот запрос

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

тоже не работает и такой тип запросов мне нужен в моем приложении. Есть ли другой способ написать так, чтобы он работал?

2 ответа

Решение

Пример из документации использует расширенный синтаксис запроса. Проверь это PRAGMA compile_options; включает в себя ENABLE_FTS3_PARENTHESIS,

Что твой NEAR запрос не работает не проблема с параметрами компиляции:

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

Проблема в том, что, согласно документации, NEAR работает только с основными поисковыми выражениями:

Запрос NEAR задается путем помещения ключевого слова "NEAR" между двумя запросами фразы, термина или префикса.

Таким образом, вы должны переписать поисковое выражение соответственно:

> 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

Я не знаю, является ли это документами или это ошибка в SQLite, но вот несколько альтернатив:

За AND запросы

Не работает:

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

Работает (используя подразумеваемый AND):

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

OR похоже на работу

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

За OR + NEAR запросы:

Не работает:

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

Работает:

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

РЕДАКТИРОВАТЬ: Для формы, упомянутой в комментариях (word11 OR word12 OR word13) NEAR/2 (word21 OR word22 OR word23) NEAR/2 (word31 OR word32 OR word33, Это лучшее, что я мог сделать, это собрать все комбинации вместе с 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'
...

Выше, конечно, создает большое количество SQL. Если ваши слова похожи в том, что отличаются только окончания, вы можете использовать подстановочные знаки:

SELECT * FROM docs WHERE docs MATCH 'word1* NEAR/2 word2* NEAR/2 word3*';

Согласно документации ( https://www.sqlite.org/fts3.html) круглые скобки по умолчанию не поддерживаются.

Посмотрите часть 2. Компиляция и включение FTS3 и FTS4.

Другие вопросы по тегам