mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-30 19:00:29 +08:00
Prevent rank change in case of duplicate search terms
This commit is contained in:
parent
5d5087363d
commit
31b6d840f6
@ -43,6 +43,8 @@ static float weights[] = {0.1, 0.2, 0.4, 1.0};
|
|||||||
|
|
||||||
#define DEF_NORM_METHOD 0
|
#define DEF_NORM_METHOD 0
|
||||||
|
|
||||||
|
static float calc_rank_or(float *w, tsvector * t, QUERYTYPE * q);
|
||||||
|
static float calc_rank_and(float *w, tsvector * t, QUERYTYPE * q);
|
||||||
/*
|
/*
|
||||||
* Returns a weight of a word collocation
|
* Returns a weight of a word collocation
|
||||||
*/
|
*/
|
||||||
@ -112,6 +114,55 @@ find_wordentry(tsvector * t, QUERYTYPE * q, ITEM * item)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char * SortAndUniqOperand=NULL;
|
||||||
|
|
||||||
|
static int
|
||||||
|
compareITEM( const void * a, const void * b ) {
|
||||||
|
if ( (*(ITEM**)a)->length == (*(ITEM**)b)->length )
|
||||||
|
return strncmp( SortAndUniqOperand + (*(ITEM**)a)->distance,
|
||||||
|
SortAndUniqOperand + (*(ITEM**)b)->distance,
|
||||||
|
(*(ITEM**)b)->length );
|
||||||
|
|
||||||
|
return ((*(ITEM**)a)->length > (*(ITEM**)b)->length) ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ITEM**
|
||||||
|
SortAndUniqItems( char *operand, ITEM *item, int *size ) {
|
||||||
|
ITEM **res, **ptr, **prevptr;
|
||||||
|
|
||||||
|
ptr = res = (ITEM**) palloc( sizeof(ITEM*) * *size );
|
||||||
|
|
||||||
|
while( (*size)-- ) {
|
||||||
|
if ( item->type == VAL ) {
|
||||||
|
*ptr = item;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
item++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*size = ptr-res;
|
||||||
|
if ( *size < 2 )
|
||||||
|
return res;
|
||||||
|
|
||||||
|
SortAndUniqOperand=operand;
|
||||||
|
qsort( res, *size, sizeof(ITEM**), compareITEM );
|
||||||
|
|
||||||
|
ptr = res + 1;
|
||||||
|
prevptr = res;
|
||||||
|
|
||||||
|
while( ptr - res < *size ) {
|
||||||
|
if ( compareITEM( (void*) ptr, (void*) prevptr ) != 0 ) {
|
||||||
|
prevptr++;
|
||||||
|
*prevptr = *ptr;
|
||||||
|
}
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*size = prevptr + 1 - res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static WordEntryPos POSNULL[] = {
|
static WordEntryPos POSNULL[] = {
|
||||||
0,
|
0,
|
||||||
0
|
0
|
||||||
@ -120,7 +171,7 @@ static WordEntryPos POSNULL[] = {
|
|||||||
static float
|
static float
|
||||||
calc_rank_and(float *w, tsvector * t, QUERYTYPE * q)
|
calc_rank_and(float *w, tsvector * t, QUERYTYPE * q)
|
||||||
{
|
{
|
||||||
uint16 **pos = (uint16 **) palloc(sizeof(uint16 *) * q->size);
|
uint16 **pos;
|
||||||
int i,
|
int i,
|
||||||
k,
|
k,
|
||||||
l,
|
l,
|
||||||
@ -132,19 +183,22 @@ calc_rank_and(float *w, tsvector * t, QUERYTYPE * q)
|
|||||||
lenct,
|
lenct,
|
||||||
dist;
|
dist;
|
||||||
float res = -1.0;
|
float res = -1.0;
|
||||||
ITEM *item = GETQUERY(q);
|
ITEM **item;
|
||||||
|
int size = q->size;
|
||||||
|
|
||||||
memset(pos, 0, sizeof(uint16 **) * q->size);
|
item = SortAndUniqItems( GETOPERAND(q), GETQUERY(q), &size);
|
||||||
|
if ( size < 2 ) {
|
||||||
|
pfree(item);
|
||||||
|
return calc_rank_or(w, t, q);
|
||||||
|
}
|
||||||
|
pos = (uint16 **) palloc(sizeof(uint16 *) * q->size);
|
||||||
|
memset(pos, 0, sizeof(uint16 *) * q->size);
|
||||||
*(uint16 *) POSNULL = lengthof(POSNULL) - 1;
|
*(uint16 *) POSNULL = lengthof(POSNULL) - 1;
|
||||||
WEP_SETPOS(POSNULL[1], MAXENTRYPOS-1);
|
WEP_SETPOS(POSNULL[1], MAXENTRYPOS-1);
|
||||||
|
|
||||||
for (i = 0; i < q->size; i++)
|
for (i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
|
entry = find_wordentry(t, q, item[i]);
|
||||||
if (item[i].type != VAL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
entry = find_wordentry(t, q, &(item[i]));
|
|
||||||
if (!entry)
|
if (!entry)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -181,6 +235,7 @@ calc_rank_and(float *w, tsvector * t, QUERYTYPE * q)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pfree(pos);
|
pfree(pos);
|
||||||
|
pfree(item);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,16 +248,15 @@ calc_rank_or(float *w, tsvector * t, QUERYTYPE * q)
|
|||||||
j,
|
j,
|
||||||
i;
|
i;
|
||||||
float res = -1.0;
|
float res = -1.0;
|
||||||
ITEM *item = GETQUERY(q);
|
ITEM **item;
|
||||||
|
int size = q->size;
|
||||||
|
|
||||||
*(uint16 *) POSNULL = lengthof(POSNULL) - 1;
|
*(uint16 *) POSNULL = lengthof(POSNULL) - 1;
|
||||||
|
item = SortAndUniqItems( GETOPERAND(q), GETQUERY(q), &size);
|
||||||
|
|
||||||
for (i = 0; i < q->size; i++)
|
for (i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
if (item[i].type != VAL)
|
entry = find_wordentry(t, q, item[i]);
|
||||||
continue;
|
|
||||||
|
|
||||||
entry = find_wordentry(t, q, &(item[i]));
|
|
||||||
if (!entry)
|
if (!entry)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -225,6 +279,7 @@ calc_rank_or(float *w, tsvector * t, QUERYTYPE * q)
|
|||||||
res = 1.0 - (1.0 - res) * (1.0 - wpos(post[j]));
|
res = 1.0 - (1.0 - res) * (1.0 - wpos(post[j]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pfree( item );
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,7 +404,7 @@ checkcondition_DR(void *checkval, ITEM * val)
|
|||||||
|
|
||||||
while (ptr - ((ChkDocR *) checkval)->doc < ((ChkDocR *) checkval)->len)
|
while (ptr - ((ChkDocR *) checkval)->doc < ((ChkDocR *) checkval)->len)
|
||||||
{
|
{
|
||||||
if (val == ptr->item)
|
if ( val == ptr->item || compareITEM( &val, &(ptr->item) ) == 0 )
|
||||||
return true;
|
return true;
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
@ -439,6 +494,7 @@ Cover(DocRepresentation * doc, int len, QUERYTYPE * query, int *pos, int *p, int
|
|||||||
ch.doc = f;
|
ch.doc = f;
|
||||||
ch.len = (doc + lastpos) - f + 1;
|
ch.len = (doc + lastpos) - f + 1;
|
||||||
*pos = f - doc + 1;
|
*pos = f - doc + 1;
|
||||||
|
SortAndUniqOperand = GETOPERAND(query);
|
||||||
if (TS_execute(GETQUERY(query), &ch, false, checkcondition_DR))
|
if (TS_execute(GETQUERY(query), &ch, false, checkcondition_DR))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user