Ошибка полнотекстового поиска SQLite FTS5

orka13

Client
Регистрация
07.05.2015
Сообщения
2 177
Благодарностей
2 184
Баллы
113
Хочу подключить таблицу в формате SQLite FTS5 (кому интерестно - подробнее на русском есть мануал о FTS3\FTS4) для полнотекстового поиска\выборки. То есть фактически только Read-only операции буду делать. Но обычным кубиком не получается.
Как недостающий модуль подключить? Пробовал и на старом FTS3 делать БД, результат тот же. ZennoPoster 5.9.9.1 \ 5.10.4.1 (последний). Windows 10 x64. Я новичок в БД, но на локальном ПК в cmd\sqlite3 получилось делать импорт\выборки в такой базе, в зенке нет. Можете и на c# кубике что-то посоветовать.
Код ошибки: Db ERROR [HY000] no such module: fts5 (1)
Скрины ZP \ PM:




UPD:
гуглил, нашел что что-то о правках в с#. Если никто здесь не посоветует легкого решения, то придется внедрять это в кубике c#. Я в этом не особо силен, но видел на форуме примеры.
 
Последнее редактирование:

orka13

Client
Регистрация
07.05.2015
Сообщения
2 177
Благодарностей
2 184
Баллы
113
Если кому-то будет интересно как создать такую БД, то поделюсь способом для таких же новичков как я с нуля:

1. Чтобы понять суть БД на примере SQLite смотрим хотя бы первые 10-30 маленьких уроков отсюда https://www.youtube.com/playlist?list=PLeYxjiX1MAInukqt-0XKbG9qP2j0QovZH (русскоязычных мануалов очень мало в сети).
2. Готовим файл для импорта в БД, у меня это «file_csv.txt», строки с двумя столбцами, разделенными пробельным табом (\t). Двойные кавычки экранированы (замените " на "") , и сами блоки (столбцы) текста возьмите в кавычки. Пример строки с двумя столбцами:
Код:
"092345234"  "тут начинается второй столбец с любым текстом, можно и с двойными кавычками "", но с одинарной кавычкой в конце"
3. Запускаем командную строку с установленный sqlite3 с папки где у нас файл file_csv.txt. Вводим:
Код:
-- cсоздаем виртуальную таблицу на 2 столбца:
CREATE VIRTUAL TABLE test USING fts5(id, text);
-- или же используйте метод с токенайзером "porter" (будет распознавать морфологию еще лучше): CREATE VIRTUAL TABLE test USING fts5(id, text, tokenize = 'porter');
-- указываем что у нас разделитель в файле импорта знак табуляции \t, или же в кавычках укажите свой разделитель (например ";")
.separator \t
-- импортируем в таблицу наш файл
.import file_csv.txt test
-- делаем оптимизацию как http://xbb.uz/db/SQLite-FTS3-i-FTS4/#section_1_3
INSERT INTO test(test) VALUES('optimize');
-- сохраняем в файл
.save dbfile.db
-- пример поиска с ограничением в 10 строк:
SELECT * FROM test WHERE test MATCH 'fraza poiska' LIMIT 10;
-- выходим
.exit
В БД на 700 мб (200К длинных строк строк-статтей, 77КК слов) моментально ищет релевантные строки по заданной фразе (почти как через гугл по документам искать). Правда у меня латиница, хз как с кириллицей работает.

UPD:
Пример шаблона с мелкими файлами БД и Импорта: Скачать
 
Последнее редактирование:

orka13

Client
Регистрация
07.05.2015
Сообщения
2 177
Благодарностей
2 184
Баллы
113
Все ети дни я искал инфу в сети. Походу без C# не обойтись, поскольку стандартным методом зенки через драйвер ODBC нет поддержки FTS по умолчанию. Пишут что надо рекомпилить - http://stackoverflow.com/questions/17346131/fts4-available-in-sqlite-odbc-driver/17348205#17348205 , но я не умею.

Изучал темы на форуме с C# примерами. Там куча нюансов для организации работы. К примеру, работает с обычной SQLite (не FTS) вот с этого поста вариант.

Я его переделал под свои столбцы. Но учтите, что у меня “Windows 10 x64”, и надо было залить в папку c:\Program Files (x86)\ZennoLab\ZennoPoster Pro\Progs\ExternalAssemblies\ файлы System.Data.SQLite.dll и SQLite.Interop.dll из sqlite-netFx40-binary-Win32-2010-1.0.104.0.zip из http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki (прикрепляю их в архиве с шаблоном). И это помогает только для работы в ProjectMaker, поскольку он 32-разрядный и на основе «.NET Framework 4». А для успешного выполнения шаба в ZennoPoster подошли Файлы из sqlite-netFx46-binary-x64-2015-1.0.104.0.zip. Об этом писалось в теме на форуме.



Код:
string result = String.Empty;
string connectionString = project.Variables["connectionString"].Value;
var query = new DataTable();
try
{
    using (var sqLiteConnection = new System.Data.SQLite.SQLiteConnection(connectionString))
    {
        sqLiteConnection.Open();
        using (var cmd = new System.Data.SQLite.SQLiteCommand(sqLiteConnection) {CommandText = "Select * from test"})
        {
            var reader = cmd.ExecuteReader();
            query.Load(reader);
        }
    }
}
catch(Exception ex)
{
    project.SendErrorToLog(ex.Message, "sqlite error");
    return result;
}

DataRow[] data = query.Select();
foreach (DataRow row in data)
{
    if (!String.IsNullOrWhiteSpace(result)) result = String.Format("{0}\r\nid: {1}; text: {2}", result, row["id"], row["text"]);
    else result = String.Format("id: {0}; text: {1}", row["id"], row["text"]);
}

return result;
Получается шаб на C# у меня полу-рабочий (в обычной не-FTS базе выборки норм делает). И есть подсказка как подружить его с FTS здесь - http://stackoverflow.com/questions/37565423/sqlite-no-such-module-fts5-error-with-system-data-sqlite-dll-1-0-101-0 . Вроде как надо куда то добавить:

Код:
MyConnection.EnableExtensions(True)
MyConnection.LoadExtension("System.Data.SQLite.dll", "sqlite3_fts5_init") ''/// Or "SQLite.Interop.dll" as you need.
Но куда и как? Короче, надо подсказки от знающих синтаксис C# людей. Ибо я не кодер. И походу в этом «добавлении» надо поменять «MyConnection» на «sqLiteConnection», ибо в моем куске кода именно так обозначено подключение. На stackoverflow.com в комментариях автор пишет что толи этот код, то ли запросы должны идти после ".Open()" ("Also note that code must be after MyConnection.Open()"), но я не понял инфы до конца.

Прикрепляю архив с шабом. В нем все файлы. По умолчанию прописана работа с файлом «dbfile_fts5.db», но понятно, что его не обрабатывает. Только файл «dbfile_no_fts.db» кушает.

www.orka13.ru/fls/f/Parser_SQLite_forum_C.zip
 
Последнее редактирование:

orka13

Client
Регистрация
07.05.2015
Сообщения
2 177
Благодарностей
2 184
Баллы
113
поправка: оказывается, шаблон из предыдущего поста работает не только с обычными базами, но и с FTS3\FTS4 базами, правда все еще не работает с FTS5. Шаблон без C# (на зеновкском кубике) из первого поста только обычные базы распознает.
Если не получится ничего придумать, то перейду на FTS4.
 

orka13

Client
Регистрация
07.05.2015
Сообщения
2 177
Благодарностей
2 184
Баллы
113
Высота взята! Погуглил я фразу «sqlite3_fts5_init» из той статьи на stackoverflow.com. Нашел рабочий пример с подключением FTS5: http://pastebin.com/9CB4Mn2J
Переделал под себя (просто две строки добавил), и все получилось. Вот рабочий пример:
Код:
string result = String.Empty;
string connectionString = project.Variables["connectionString"].Value;
var query = new DataTable();
try
{
    using (var sqLiteConnection = new System.Data.SQLite.SQLiteConnection(connectionString))
    {
    
        sqLiteConnection.Open();
        sqLiteConnection.EnableExtensions(true);
        sqLiteConnection.LoadExtension("SQLite.Interop.dll", "sqlite3_fts5_init");

        using (var cmd = new System.Data.SQLite.SQLiteCommand(sqLiteConnection) {CommandText = "Select * from test"})
        {
            var reader = cmd.ExecuteReader();
            query.Load(reader);
        }
    }
}
catch(Exception ex)
{
    project.SendErrorToLog(ex.Message, "sqlite error");
    return result;
}

DataRow[] data = query.Select();
foreach (DataRow row in data)
{
    if (!String.IsNullOrWhiteSpace(result)) result = String.Format("{0}\r\nid: {1}; text: {2}", result, row["id"], row["text"]);
    else result = String.Format("id: {0}; text: {1}", row["id"], row["text"]);
}

return result;
 
Последнее редактирование:

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)