Posts

Showing posts with the label FTS

FTS3 Snowball Stemmer

Итак, поддержка стеммеров snowball для SQLite: http://sqlite.mobigroup.ru/wiki?name=FTS3+Snowball+Stemmer Пример использования: CREATE VIRTUAL TABLE fts USING fts4(text,TOKENIZE icu russian); insert into fts (text) values ('Нафига'); insert into fts (text) values ('попу'); insert into fts (text) values ('наган'); insert into fts (text) values ('если'); insert into fts (text) values ('поп'); insert into fts (text) values ('не'); insert into fts (text) values ('хулиган'); select * from fts where fts match 'поп'; попу поп sqlite> select * from fts where fts match 'нафиг'; Нафига Примечание: аналогично можно использовать и fts3 виртуальные таблицы, но рекомендуется переходить на fts4.

zlib-enabled FTS3 for SQLite 2.6.23

Выложил свои патчи для zlib-сжатия в модуле полнотекстового поиска FTS3 для SQLite, теперь база данных с полнотекстовым индексом примерно вчетверо компактнее. Патч брать здесь: http://sqlite.mobigroup.ru/src/vinfo/d3d9906674 и функции сжатия/распаковки здесь: http://sqlite.mobigroup.ru/src/dir?name=ext/compress Или качать последнюю версию моей сборки деб-пакета SQLite. Имеется одна неприятность - запрос count(*) выполняется медленно, т.к. приводит к распаковке всего контента базы, так уж в эскулайт работает интерфейс виртуальных таблиц. Решения пока не нашел, но есть обходной путь - обращаться напрямую к таблице %_content: sqlite> select count(*) from file_text; 8430 CPU Time: user 0.508032 sys 0.012000 sqlite> select count(*) from file_text_content; 8430 CPU Time: user 0.004000 sys 0.000000 С учетом размеров современных электронных библиотек считаю, что сжатие критически необходимо, потому и выкладываю патч с вышеназванной недоработкой.

Словари для полнотекстового поиска

КОгда-то я тестировал поиск по словарю, для этого конвертировал словари myspell. А теперь существует и стандартная утилит для этого: $ apt-file search pg_updatedicts postgresql-common: /usr/sbin/pg_updatedicts postgresql-common: /usr/share/man/man8/pg_updatedicts.8.gz man pg_updatedicts PG_UPDATEDICTS(8) Debian PostgreSQL infrastructure PG_UPDATEDICTS(8) NAME pg_updatedicts - build PostgreSQL dictionaries from myspell/hunspell ones SYNOPSIS pg_updatedicts DESCRIPTION pg_updatedicts makes dictionaries and affix files from installed myspell and hunspell dictionary packages available to PostgreSQL for usage with tsearch and word stem support. In particular, it takes all *.dic and *.aff files from /usr/share/myspell/dicts/, converts them to UTF-8, puts them into /var/cache/postgresql/dicts/ with *.dict and *.affix suffixes, and symlinks them into /usr/share/postgresql/>version/tsearch_data/system_*, where Po...

Производительность SQLite FTS3

Возвращаясь к вопросу о производительности модуля полнотекстового поиска в SQLite, мы можем наблюдать весьма приятную картину: $ ls -lh|grep test.db|awk '{print $5}' 15G $ sqlite3 test.db SQLite version 3.6.21 sqlite> select count(*) from file_text; 908800 sqlite> select total(length(content)) from file_text; 6552194816.0 sqlite> select count(docid) from file_text where file_text match 'претензия'; 1536 CPU Time: user 0.004001 sys 0.000000 sqlite> select count(docid) from file_text where file_text match 'новости август абонент'; 256 CPU Time: user 0.028002 sys 0.000000 sqlite> select count(docid) from file_text where file_text match 'новости август абонент*'; 512 CPU Time: user 0.420026 sys 0.000000 Резюме : набор из почти миллиона документов общим размером 100 Гб, суммарно содержащих 6,5 миллиардов знаков, хранится в 15 Гб БД и поиск по одному слову занимает единицы миллисекунд, по нескольким словам - десятки миллисекунд, по нескольким сл...

Извлечение метаинформации о файлах

Получение метаинформации о файлах необходимо, например, для систем полнотекстового поиска. Для этих целей применяются более или менее навороченные скрипты, поставляемые в комплекте. Для меня подобный подход неприемлем, что и побудило меня поискать unix-way для решения поставленной задачи. И он нашелся - это утилита extract из одноименного пакета. Пример использования: $ extract MTS\ Connect.ppt mimetype - application/vnd.ms-powerpoint paragraph count - 215 title - PowerPoint Presentation word count - 741 date - 2008-12-29T09:30:08Z generator - Microsoft PowerPoint last saved by - Иван Иваныч creation date - 2009-04-22T19:24:48Z Что и требовалось получить.

Фильтры для преобразования ms excel и ms powerpoint в html и текст

Вот и еще пара нужных фильтров, притом шустрых и без ветвистых зависимостей. application/vnd.ms-excel #!/bin/sh nice -n19 xlhtml "$1" | \ grep -v 'Created with <a href="http://chicago.sf.net/xlhtml">xlhtml 0.5.1' \ |w3m \ -o indent_incr=0 \ -o multicol=false \ -o no_cache=true \ -o use_cookie=false \ -o display_charset=utf8 \ -o system_charset=utf8 \ -o follow_locale=false \ -o use_language_tag=true \ -o ucs_conv=true \ -T text/html \ -dump application/vnd.ms-office #!/bin/sh nice -n19 ppthtml "$1" \ |grep -v 'Created with <a href="http://chicago.sf.net/xlhtml">pptHtml' \ |w3m \ -o indent_incr=0 \ -o multicol=false \ -o no_cache=true \ -o use_cookie=false \ -o display_charset=utf8 \ -o system_charset=utf8 \ -o follow_locale=false \ -o use_language_tag=true \ -o ucs_conv=true \ -T text/html \ -dump И все больше не пон...

Фильтр для преобразования odt в html

Самый что ни на есть распрекрасный odt тоже нужно индексировать. "С помощью лома и какой-то матери" нашел ODF Tools , которые производят на свет неплохой html. Опять же, плодя временные файлы. Единственный плюс сего проекта - дают адекватную xslt-таблицу преобразования. Но что они с ней вытворяют, это же уму не постижимо. Чтение исходников привело к мысли, что все гораздо проще делается, например, так cat <(echo "<?xml version='1.0' encoding='UTF-8'?>")\ <(echo "<office:document xmlns:office='urn:oasis:names:tc:opendocument:xmlns:office:1.0'>")\ <(unzip -p 101.odt meta.xml |grep -v "<?xml version=") \ <(unzip -p 101.odt content.xml |grep -v "<?xml version=") \ <(unzip -p 101.odt styles.xml |grep -v "<?xml version=") \ <(echo "</office:document>")\ |xsltproc odt2html.xsl - Оно работает, и без временных файлов. Но, как я понимаю, это "башиз...

Some enhancements for FTS3

The FTS3 work fine but is really unfriendly to developers. As example it is easy to write tcl interface code for snowball stemmer utility "stemwords" and for stopwords dictionary but there are no ways to use it in FTS3. The user functions can be easy writed on C or any other language but FTS3 does not work with these. 1. There are no interfaces for stemmer, stopwords dictionary, etc. in the FTS3 extension. It's very difficult to understand the code of FTS3 extension and change it. Is it possible to add calls of user-defined functions for this tasks? The virtual table creating command may be extended as sql-command ::= CREATE VIRTUAL TABLE [ database-name .] table-name USING fts3 [( [ argument [, argument, [argument, ...] ]*] )] argument ::= name | TOKENIZE tokenizer | FUNCTION user_function tokenizer ::= SIMPLE | PORTER | user-defined When FUNCTION return null than the word must be ignored else the tokenized word is replaced by returned from function. As example applicati...

The Tcl documents scanner for FTS3

The useful scanner may collect as documents body as meta information. For start we can store the type, size and some checksum for original file. #!/usr/bin/tclsh8.5 # find /mnt/backup/project/offline1/www/share | ./scan.tcl /mnt/backup/project/offline1/www/share package require sqlite3 catch {file delete scan.db} sqlite3 db scan.db #sqlite3 db :memory: db eval { CREATE TABLE file ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, save_date REAL NOT NULL DEFAULT (julianday('now')), delete_date REAL, checksum text not null, uri text not null, size int not null, mime text not null default '' ); CREATE VIRTUAL TABLE file_text USING fts3(content, TOKENIZE icu ru_RU); } # cut the root directory name from file names set root [lindex $argv 0] while {[eof stdin] == 0} { set file [gets stdin] catch { if {[file type $file] ne {file}} continue set mime [exec file --brief --mime-type $file] if {[file exists ./filters/${mime}_...

Tests of the Zlib-patched FTS3

The test suite is simple. Are using tcl script to scan directories and some filters are based on the tracker project filters. I don't use transactions in my tests but it's easy to change tcl script for outher tests. The pragmas values are page_size=4096 and cache_size=128000 in my SQLite build. The scanned directory have a subdirectories and a files of different types. $ du -sh /mnt/backup/project/offline1/www/share 290M /mnt/backup/project/offline1/www/share $ find /mnt/backup/project/offline1/www/share -type f|wc -l 7122 $ find /mnt/backup/project/offline1/www/share -type f|grep .html|wc -l 4321 $ find /mnt/backup/project/offline1/www/share -type f|grep .doc|wc -l 89 $ find /mnt/backup/project/offline1/www/share -type f|grep .xsl|wc -l 37 $ find /mnt/backup/project/offline1/www/share -type f|grep .pdf|wc -l 4 The test Tcl script. #!/usr/bin/tclsh8.5 # ./scan.tcl /mnt/backup/project/offline1/www/share package require sqlite3 sqlite3 db scan.db db eval {CREATE VIRTUAL TABLE ...

The Zlib Compression Patch for the FTS3 Extension

I did try to add the zlib compression to the FTS3 extension for document content and metadata. The result you can see below. The code is only prototype but it's simple. The functions compress() and uncompress() are published by DRH here: Re: [sqlite] Compress function . I did wrap these to the compression extension . The original FTS3: $ sqlite3 SQLite version 3.6.19 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> CREATE VIRTUAL TABLE t USING fts3(content, TOKENIZE icu ru_RU); sqlite> insert into t (content) values(' ...> - работай, как будто тебе не надо денег, ...> - люби, как будто тебе никто никогда не причинял боль, ...> - танцуй, как будто никто не смотрит, ...> - пой, как будто никто не слышит, ...> - живи, как будто на земле рай'); sqlite> sqlite> insert into t (content) values(' ...> Среди миров ...> ...> Среди миров, в мерцании светил ...> Одной Звезды я повторяю ...

Полнотекстовый поиск: первое приближение

Нулевое приближение заключалось в изучении вопроса. Результатом стала утвердившаяся мысль о том, что мы понятия не имеем о принципах мышления и способах коммуникации между мыслящими существами. В числе прочего набрел на исследование, авторы которого утверждают, что знание хотя бы одного иностранного языка есть гарантия от маразма и прочих напастей в преклонном возрасте. Как следствие, подумал вот о чем - неумение компьютеров анализировать тексты позволяет предположить их склонность к умопомрачению. В том смысле, что полученные результаты могут быть представлены в совершенно бредовом, с человеческой точки зрения, виде. Например, недавно гуглил информацию по коробкам для розеток, и что же - на каждой странице с десятком результатов поиска была ссылка на танк! Ну, тоже коробка, конечно... в некотором роде. И даже розетки в этой "коробке" наверняка есть. Интересно следующее - собственно поиск особых сложностей не представляет, а вот ранжирование результатов доступно или в предела...