Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Postgres i Full Text Search

8 views
Skip to first unread message

fReLuZ

unread,
Jun 11, 2005, 3:11:04 PM6/11/05
to
Wlasnie dobieram baze danych, w ktorej w jednym z pol beda prezchowywane
dosc dlugie string tak do 4 kilobajtow (powiedzmy okolo 5000 - 10000
rekordow).

No i niestety na tych rekordach beda czesto wykonywane zapytania no i
wlasnie chce aby zostaly one poindexowane i mysle nad nastepujacymi bazami:


MySQL - wyczytalem ze posiada Full Text Search wbudowane:):), niestety
licencja jest niezbyt korzystna :(

MS SQL - niestety drogi :(:( brak wersji na Linuxa :(

MS MSDE - brak wersji na Linuxa, przyjemna licencja :), z tego co
wyczytalem nie ma Full Text Search (chociaz myslalem ze to korzysta z
systemu http://www.mcse.ms/message1635107.html):(:(

Postgres - licencja super:):), na MS Windows i Linux:), z tego co
doczytalem to aby miec Full Text Search trzeba cos doinstalowywac no i
tu sie robi problem, bo uzytkownik moze miec problem z doinstalowaniem
czegosc.. pozatym nie jestem pewien czy wersja na Windows ma ten
dodatkowy modul do Full text Search.:(:(

Firebird - brak doswiadczenia z ta baza danych,:( ale Full Text Search
tez chyba jest realizowany zewnetrznie?:(


Jaka w takim razie baze danych polecicie?


PS
Wlasnie dodalem :( oraz :) przy bazach i wynika mi z tego ze MySQL... co
wy na ten temat sadzicie?

Piotr 'piter' Hlawski

unread,
Jun 11, 2005, 3:31:57 PM6/11/05
to
fReLuZ wrote:

[...]

> Postgres - licencja super:):), na MS Windows i Linux:), z tego co
> doczytalem to aby miec Full Text Search trzeba cos doinstalowywac no i
> tu sie robi problem, bo uzytkownik moze miec problem z doinstalowaniem
> czegosc.. pozatym nie jestem pewien czy wersja na Windows ma ten
> dodatkowy modul do Full text Search.:(:(

[...]

PostgreSQL, ma fulltext search po przez tsearch2
(http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/), dostępny w
Contrib. Windowsowa instalka wersji 8.x Pg AFAIK ma to w default
(zaznaczsz tylko w opcjach, że chcesz używać). W Unixach wymaga to
pewnych kilku prostych zabiegów. Obydwie wersje wymagają trochę
poczytania jak się z tym obchodzić (głównie chodzi tu o indexowanie i
skonfigurowanie słownika). Całość chodzi naprawdę sprawnie i szybko -
testowałem na tablicy z około półtora miliona rekordów. Jeden
disadvantage :/ - całość indexuje w oparciu o słownik, a więc zdanie
"Ale tutaj jest diabelsko wesoło" rozdzieli mniej więcej na słowa:
ale|tutaj|jest|diabeł|wesoło (słownik załatwia odmiany), więc zapomnij o
tym że ci wyszuka rekordy na zasadzie '%weso%', partial search na takim
indexie _nie_ zadziała.
Pozatym całkiem fajne.

PS. A jeśli osobiście ogólnie polecać bazę to jak najbardziej Pg :-)

--
.:: Piter // do...@op.pl // gg: 4534287 ::.
A czym się różni Cray od normalnego peceta?
Tym, że Cray wykonuje pętle nieskończone w 10 sekund

fReLuZ

unread,
Jun 11, 2005, 3:41:07 PM6/11/05
to

> disadvantage :/ - całość indexuje w oparciu o słownik, a więc zdanie
> "Ale tutaj jest diabelsko wesoło" rozdzieli mniej więcej na słowa:
> ale|tutaj|jest|diabeł|wesoło (słownik załatwia odmiany), więc zapomnij o
> tym że ci wyszuka rekordy na zasadzie '%weso%', partial search na takim


"Ale tutaj jest diabelsko wesoło" - chodzi mi o to aby dalo sie wyszukac
'%diabelsko%' ? - da sie?

a jak sie da wyszukieanie '%diabel%' to znajdzie to 'diabelsko'???

Piotr 'piter' Hlawski

unread,
Jun 11, 2005, 3:55:07 PM6/11/05
to
fReLuZ wrote:

>
>> disadvantage :/ - całość indexuje w oparciu o słownik, a więc zdanie
>> "Ale tutaj jest diabelsko wesoło" rozdzieli mniej więcej na słowa:
>> ale|tutaj|jest|diabeł|wesoło (słownik załatwia odmiany), więc zapomnij o
>> tym że ci wyszuka rekordy na zasadzie '%weso%', partial search na takim
>
>
>
> "Ale tutaj jest diabelsko wesoło" - chodzi mi o to aby dalo sie
> wyszukac '%diabelsko%' ? - da sie?

Całe słowo tak, ponieważ tak zadziała słownik, że go zindexuje, że tak
powiem na pojedyńczy "atom". Jeśli jednak będziesz chciał szukać takich
rekordów gdzie kawałek tego słowa to np. '%dia%' to ni cholery... nie
przy pomocy mechanizmów tsearch2.

>
> a jak sie da wyszukieanie '%diabel%' to znajdzie to 'diabelsko'???


Jeśli dasz wyszukiwanie '%diabel%' to musisz go dać tradycyjnie SELECT
* FROM tabela WHERE pole LIKE '%diabel%', w tym momencie kompletnie nie
korzysta się z indexu tsearch2 (niestety), a co za tym idzie nie
korzystasz z full text search. Popatrz sobie na ten opis:

http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/docs/tsearch-V2-intro.html

tu jest dokładnie podane jak po poprawnym skonfigurowaniu całości
wyszukuje się korzystając z tsearch2.

Przemyslaw Popielarski

unread,
Jun 11, 2005, 4:31:52 PM6/11/05
to
fReLuZ <fre...@ibt.com.pl> wrote:
> a jak sie da wyszukieanie '%diabel%' to znajdzie to 'diabelsko'???

Wtrace tylko, ze w MySQL mozesz wyszukiwac pelnotekstowo znajac poczatek
slowa. I dodam, ze Twoje porownanie licencji GPL to licencji MS i
stwierdzenie, ze to ta druga jest wlasnie "przyjemna", sprawilo, ze spadlem
z krzesla.

--
./ premax
./ premax@hot,pl
./ koniec i bomba, a kto czytal ten traba. w.g.

fReLuZ

unread,
Jun 11, 2005, 5:22:25 PM6/11/05
to
> Wtrace tylko, ze w MySQL mozesz wyszukiwac pelnotekstowo znajac
poczatek
> slowa. I dodam, ze Twoje porownanie licencji GPL to licencji MS i
> stwierdzenie, ze to ta druga jest wlasnie "przyjemna", sprawilo, ze
> spadlem z krzesla.


heh.. wlasnie mi uswiadomiles, ze gdybym nie znal zalozen mojego
projektu to tez bym tak powiedzial, ale akurat w tym przypadku
(komercyjna aplikacja) sprawia, ze za MySQLa (jezeli chcemy dolaczyc
trzeba zaplacic (jezeli nei chcemy dolaczyc a wykorzystac connectory to
tez) i to chyba za kazda sprzedana sztuke... natomiasy MS SQL (MSDE)
mozesz rozprowadzac ze swoimi produktami (pod pewnymi warunkami)

Przemyslaw Popielarski

unread,
Jun 11, 2005, 6:55:07 PM6/11/05
to
fReLuZ <fre...@ibt.com.pl> wrote:
> (MSDE) mozesz rozprowadzac ze swoimi produktami (pod pewnymi
> warunkami)

Jednym z tych warunkow jest to, zeby miec licencje na Windows. No to co za
roznica, czy zmuszasz swojego klienta do zaplacenia za system operacyjny,
czy pozwalasz mu zoaszczedzic na o/s i czesc tych pieniedzy przeznaczyc na
rdbms?

fReLuZ

unread,
Jun 12, 2005, 5:04:29 AM6/12/05
to
> Jednym z tych warunkow jest to, zeby miec licencje na Windows. No to co
> za roznica, czy zmuszasz swojego klienta do zaplacenia za system
> operacyjny, czy pozwalasz mu zoaszczedzic na o/s i czesc tych pieniedzy
> przeznaczyc na rdbms?
>

1. Windows jest praktycznie w kazdej firmie i logiczne (w panstwie
prawa), ze jezeli instalujessz MSDE to na LEGALNYM Windowsie.

2. A bodajrze jak masz Visual Stodio to MSDE mozesz redystrybuowac.

Sergiusz Różański

unread,
Jun 12, 2005, 7:07:24 AM6/12/05
to
In article <d8gtqv$4be$1...@inews.gazeta.pl>, fReLuZ wrote:
>
> 1. Windows jest praktycznie w kazdej firmie i logiczne (w panstwie
> prawa), ze jezeli instalujessz MSDE to na LEGALNYM Windowsie.

przeciez pośrednio jest wymóg posiadania windy w każdej większej firmie,
taka firma bez płatnika nie może działać, a płatnik bez windy.

--
*** rozanski.at.sergiusz.dot.com sq3bkn ***
*** http://jeep.comm.pl ***
*** rtg project http://gg.overwap.net ***

Przemyslaw Popielarski

unread,
Jun 12, 2005, 7:52:43 AM6/12/05
to
Sergiusz Różański <write-onl...@sergiusz.com> wrote:
> przeciez pośrednio jest wymóg posiadania windy w każdej większej
> firmie, taka firma bez płatnika nie może działać, a płatnik bez windy.

AFAIK wraz z ostatnia akttalizacja do pp sie to zmienilo -- bo jest tam
jakas taka opcja, ze to strona trzecia moze wysylac Platnikiem dokumenty do
ZUS po upowaznieniu przez Ciebie. Czyli placisz biurze ksiegowemu i masz
Windows z glowy.

Ronald Kuczek

unread,
Jun 12, 2005, 3:51:42 PM6/12/05
to
Użytkownik fReLuZ napisał:

> Wlasnie dobieram baze danych, w ktorej w jednym z pol beda prezchowywane
> dosc dlugie string tak do 4 kilobajtow (powiedzmy okolo 5000 - 10000
> rekordow).
>
> No i niestety na tych rekordach beda czesto wykonywane zapytania no i
> wlasnie chce aby zostaly one poindexowane i mysle nad nastepujacymi bazami:
>
Uderzę z innej beczki.
Jeśli szukasz bazy pełnotekstowej z prawdziwego zdarzenia zapomnij o
MySQL-u i Postgresie.
Daleko im do fulltekstów z prawdziwego zdarzenia jak Fulcrum czy Verity.
Choćby takie możliwości jak wyszukiwanie fraz, odległość słów,
wildcards, fuzzy logic...
Zastanów się również, czy musisz koniecznie mieć RDBMS. Znacznie
wydajniejsze może być rozwiązanie (darmowe zresztą) takie jak swish-e
czy swish++.
http://swish-e.org/
http://homepage.mac.com/pauljlucas/software/swish/
Dobrym pomysłem jest też np. połączenie swish-a np. postgresem czy
firebirdem. Sprawdziłem osobiście, wyniki są rewelacyjne.

Pozdrawiam
Rony

Sergiusz Różański

unread,
Jun 12, 2005, 4:03:54 PM6/12/05
to

no kurcze, 5+ za tą podpowiedź, odnotowane, właśnie szykuje mi się
robótka z ww. i miałem zacząć szukać mechanizmów w te klocki.

Ronald Kuczek

unread,
Jun 12, 2005, 4:14:02 PM6/12/05
to
Użytkownik Sergiusz Różański napisał:

> no kurcze, 5+ za tą podpowiedź, odnotowane, właśnie szykuje mi się
> robótka z ww. i miałem zacząć szukać mechanizmów w te klocki.

Dzięki, temat ćwiczę od 5 lat (pisałem na ten temat w Software 12/2000).
Swish++ i swish-e połączone to naprawdę niezły kawał softu ( z tym, że
od razu z doświadczenia radzę przepisać kod bazujący na mapowaniu plików
(fajne ale trzebaby mieć fabrykę RAM-ów na dłuższą metę) - i zastąpić to
seek-iem). Działa jakieś 20% wolniej ale i tak wszelkie RDBMS-y odpadają
w przedbiegach ;-)
Do RAM warto jedynie wczytać słownik. Potem tylko binary search i po
prostu bajka.
Zgrabne połączenie swisha++ i postgresa to też nie problem (odpytanie
fulltexta w funkcji SPI i wyniki w tabeli temporalnej), ja robię to tak:

#include "executor/spi.h" /* this is what you need to work with SPI */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>


#define SERVER_PORT 30000
#define SERVER_ADDRESS "localhost"
#define MAX_MSG 100
#define TEMPFILENAME "/tmp/ft_tempXXXXXX"
#define SEARCH_PREFIX "search "
#define BUF_SIZE 4096 // musi byc wieksze od 15 - "malformed query"
#define STMT_SIZE 1000


int ft_get_ex(text *sql, text *suffix);
static int getfulltext (char *server,char *query,char *tablesuffix);

static int createft_temp_ex_g(char *tablesuffix)
{
int ret;
char *stmt = (char*)calloc(STMT_SIZE,1);

strcpy(stmt,"drop table ft_temp");
strcat(stmt,tablesuffix);
SPI_exec(stmt,0);
strcpy(stmt,"create temporary table ft_temp");
strcat(stmt,tablesuffix);
strcat(stmt,"(doc_id int4,relevance int4) without oids");
ret=SPI_exec(stmt,0);
free(stmt);

return ret;

}


static int createindex_ft_ex_g(char *tablesuffix)
{
int ret;
char *stmt = (char*)calloc(STMT_SIZE,1);
strcpy(stmt,"create index ft_temp_idx_rel_doc_id");
strcat(stmt,tablesuffix);
strcat(stmt," on ft_temp");
strcat(stmt,tablesuffix);
strcat(stmt,"(relevance,doc_id);");
strcat(stmt,"create index ft_temp_idx_doc_id");
strcat(stmt,tablesuffix);
strcat(stmt," on ft_temp");
strcat(stmt,tablesuffix);
strcat(stmt,"(doc_id)");
ret=SPI_exec(stmt,0);
free(stmt);
return ret;
}

int ft_get_ex(text *sql, text *suffix)
{
char *query;
char *tablesuffix;
int ret;

/* konwertuj TEXT na C string */
query =
DatumGetCString(DirectFunctionCall1(textout,PointerGetDatum(sql)));
tablesuffix =
DatumGetCString(DirectFunctionCall1(textout,PointerGetDatum(suffix)));

SPI_connect();

createft_temp_ex_g(tablesuffix);
ret=getfulltext(SERVER_ADDRESS,query,tablesuffix);

createindex_ft_ex_g(tablesuffix);
SPI_finish();
pfree(query);
pfree(tablesuffix);
return (ret);
}

static int getfulltext (char *server,char *query,char *tablesuffix)
{
int b,ret;
int sd, rc;

char tmpfnam[]=TEMPFILENAME;
struct sockaddr_in localAddr, servAddr;
struct hostent *h;
char *query1;
unsigned char *buf = (unsigned char*)calloc(BUF_SIZE,1);
char *stmt = (char*)calloc(STMT_SIZE,1);
FILE *fp;


if ( (h = gethostbyname(server))==NULL )
return 1;

servAddr.sin_family = h->h_addrtype;
memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
servAddr.sin_port = htons(SERVER_PORT);

/* utworz socket */
if ( (sd = socket(AF_INET, SOCK_STREAM, 0))<0 )
return 2;

/* przypisz port */
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
localAddr.sin_port = htons(0);
if ( (rc = bind(sd, (struct sockaddr *) &localAddr, sizeof(localAddr)))<0 )
return 3;

/* polacz z fulltextem */
if ( (rc = connect(sd, (struct sockaddr *) &servAddr,
sizeof(servAddr)))<0 )
return -1;

query1 = (char*)calloc(strlen(query)+strlen(SEARCH_PREFIX)+2 ,1);
strcat( query1, SEARCH_PREFIX );
strcat(query1 ,query);
rc = send(sd,strcat(query1,"\n"),strlen(query1)+1, 0);

free(query1);
rc=mkstemp(tmpfnam);
close(rc);

strcpy(stmt,"copy binary ft_temp");
strcat(stmt,tablesuffix);
strcat(stmt," from '");
strcat(stmt,tmpfnam);
strcat(stmt,"'");


fp=fopen(tmpfnam,"w+");

while( (b=recv( sd, buf, BUF_SIZE, 0 )) > 0)
{
fwrite(buf,1,b,fp);
}
close (sd);
fclose(fp);
ret=SPI_exec(stmt,0);

remove(tmpfnam);
free(buf);
free(stmt);
return(ret);
}
No dość już przynudzania, w razie czego służę na priv ;-)


Pozdrawiam
Rony

fReLuZ

unread,
Jun 12, 2005, 5:41:56 PM6/12/05
to

> Zastanów się również, czy musisz koniecznie mieć RDBMS. Znacznie
> wydajniejsze może być rozwiązanie (darmowe zresztą) takie jak swish-e
> czy swish++.
> http://swish-e.org/


heh(!) No o to wlasnie chodzilo!!!

moglbys rozwinac bardziej temat "łączenie swish-a np. postgresem czy
firebirdem."

PS
swish-e.org oparte jest na GPL'u - cos innego polecicie opartego na
licencji BSD, lub podobnej do POSTGRESa?

Przemyslaw Popielarski

unread,
Jun 12, 2005, 7:17:05 PM6/12/05
to
Ronald Kuczek <kuc...@kuczek.pl> wrote:
> Jeśli szukasz bazy pełnotekstowej z prawdziwego zdarzenia zapomnij o
> MySQL-u i Postgresie.
> Daleko im do fulltekstów z prawdziwego zdarzenia jak Fulcrum czy
> Verity. Choćby takie możliwości jak wyszukiwanie fraz, odległość słów,
> wildcards, fuzzy logic...

No, frazy to MySQL ma. Wildcardy też (matchowanie koncowek slowa tak jak i w
swish). Odleglosc jest w bliskich planach, tak jak i stemming.

Ronald Kuczek

unread,
Jun 13, 2005, 4:00:18 AM6/13/05
to
Użytkownik fReLuZ napisał:

> swish-e.org oparte jest na GPL'u - cos innego polecicie opartego na
> licencji BSD, lub podobnej do POSTGRESa?

Kod źródłowy masz ;-)
Generalnie - swish-e i swish++ indeksują pliki. Jako wynik poszukiwania
dostajesz ścieżkę do pliku.
Nic nie stoi na przeszkodzie, aby źródłem tekstu były nie pliki a krotki
w bazie danych a wynik wyszukiwania był listą indentyfikatorów (w tym
kierunku poszedłem, to da się zrobić i działa bardzo wydajnie).
Fajną opcją jest możliwość wyszukiwania po tagach htmlo-wych dzięki niej
aż się prosi o zrealizowanie indeksu po polach (nie indeksujesz krotki
"jak leci") - wtedy można rozróżnić czy dana fraza pojawiła się w
tytule, tekscie czy np. przypisach dokumentu.
W poście wcześniej pokazałem fragment kodu , który używam do ściągania
danych do postgresa (reszta to zwykły join). Oczywiście musiałem
przerobić swisha, żeby indeksował krotki, ale tu już zostawiam pole do
popisu ;-)

Pozdrawiam
Rony

0 new messages