2016-12-16 2 views
1

Возможно ли до сих пор пользоваться преимуществами FTS3/4 в SQLite во время выполнения запроса с операторами AND для индексированных столбцов в виртуальной таблице? Пример:Могу ли я использовать инструкции AND в запросе FTS?

SELECT title, ID, creationDate FROM documents WHERE type=1 AND status=2 AND searchableFields MATCHES '"john doe"'; 

ИЛИ

SELECT title, ID, creationDate FROM documents WHERE type=1 AND status=2 AND searchableFields CONTAINS 'john doe'; 

Где столбцы типа и статус индексируются в виртуальной таблице.

ответ

2

Все столбцы таблицы FTS представляют собой текстовые столбцы и индексированные FTS; documentation говорит:

Если имена столбцов явно предусмотрены для таблицы FTS как часть CREATE VIRTUAL TABLE заявления, то имя типа данных может быть дополнительно указан для каждого столбца. Это чистый синтаксический сахар, поставляемые типы имен не используются FTS или ядром SQLite для любых целей.

Вы не должны делать поиск, как type=1 на столе FTS:

FTS таблицы могут быть запрошены эффективно использовать ЗЕЬЕСТ двух различных форм:

  • запрос по ROWID. Если предложение WHERE инструкции SELECT содержит подпункт формы «rowid =?», Где? является выражением SQL, FTS может получить запрошенную строку напрямую, используя эквивалент индекса SQLite INTEGER PRIMARY KEY.
  • Полнотекстовый запрос. Если предложение WHERE оператора SELECT содержит подпункт формы «MATCH?», FTS может использовать встроенный полнотекстовый индекс, чтобы ограничить поиск теми документами, которые соответствуют строке полнотекстового запроса указанный как правый операнд предложения MATCH.

Если ни одна из этих двух стратегий запроса не используется, все запросы в таблицах FTS реализуются с использованием линейного сканирования всей таблицы. Если таблица содержит большие объемы данных, это может быть непрактичным подходом.

Вы не должны рассматривать таблицу FTS как таблицу, а как индекс.

Если вы хотите сохранить нетекстовые данные, вы должны использовать отдельную нормальную таблицу и опрашивать отдельно:

SELECT title, ID, creationDate 
FROM documents 
WHERE type=1 
    AND status=2 
    AND ID IN (SELECT docid 
      FROM documents_FTS 
      WHERE searchableFields MATCH '"john doe"'); 

Чтобы избежать хранения те же данные дважды, вы можете использовать contentless or external content tables.

+0

Спасибо за ответ, это именно то, что я искал! Прежде чем отметить это как ответ, не могли бы вы также показать мне, как я могу изменить этот запрос, чтобы включить только подмножество docids, например, docids между 50-100. Причина, по которой я спрашиваю, это создать прокручиваемый список и загружать только 50 строк за раз. Благодаря! – user3367265

+0

Это был бы совсем другой вопрос. –

+0

Хорошо, если бы я опубликовал еще один вопрос, спрашивающий, что после того, как я дам вам правильный ответ на это, вы думаете, что можете мне помочь в этом, и я дам вам правильный ответ на это? Благодаря! – user3367265

Смежные вопросы