Tengo una publicación modelo:
class Post(models.Model): post_title = models.CharField(max_length=120) post_subtitle = models.TextField() post_text = models.TextField() vector_column = SearchVectorField(null=True) class Meta: indexes = (GinIndex(fields=['vector_column']),) y he creado un disparador en la base de datos para actualizar el valor de vector_column :
create function core_post_trigger() returns trigger as $$ begin new.vector_column := setweight(to_tsvector('pg_catalog.english', coalesce(new.post_title, '')), 'A') || setweight(to_tsvector('pg_catalog.english', coalesce(new.post_subtitle, '')), 'B') || setweight(to_tsvector('pg_catalog.english', coalesce(new.post_text, '')), 'C'); return new; end $$ language plpgsql; create trigger vector_column_trigger before insert or update on core_post for each row execute procedure core_post_trigger();Y busco a través de este modelo así:
Post.objects.filter(vector_column=SearchQuery(query, config='english', search_type='websearch') Aunque apliqué ponderaciones en esta búsqueda, no apliqué clasificación ( to_tsrank ). Sé que puedo aplicar rango en Django así:
vector = SearchVector('post_title', weight='A', config='english') + SearchVector('post_subtitle', weight='B', config='english') + SearchVector('post_text', weight='C', config='english') query = SearchQuery(query, search_type='websearch') Post.objects.annotate(rank=SearchRank(vector, query)).order_by('-rank') La pregunta es que no sé cómo usar SearchRank con mi columna vector_column , ya que esta columna tiene un GinIndex. Si utilizo esta variable vector creada anteriormente, no utilizaré el índice y esta búsqueda será lenta. He intentado escribir esta consulta de varias maneras, pero no sé cómo hacerlo. Probé, por ejemplo, esto:
Post.objects.annotate(SearchRank(vector_column, SearchQuery('Angel', config='english'))).order_by('-rank') Pero arroja un error vector_column is not defined .
¿Cómo puedo lograrlo?
Lo encontré. Necesitaba usar una expresión F :
Post.objects.annotate( rank=SearchRank(F('vector_column'), SearchQuery(query, config='english')) ).order_by('-rank'), 15