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?
[...]
> 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
"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'???
>
>> 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.
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.
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)
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.
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 ***
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.
Pozdrawiam
Rony
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
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?
No, frazy to MySQL ma. Wildcardy też (matchowanie koncowek slowa tak jak i w
swish). Odleglosc jest w bliskich planach, tak jak i stemming.
> 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