2016-09-12 37 views
5

Używam Django 1.10.1 przeciwko PostgreSQL 9.4. Moje stagingowe serwery i środowiska dev mają serwery psql w wersji 9.4.9, a production to RDS w wersji 9.4.7.Django psql pełna wyszukiwarka tekstowa nie pasująca do niezałamionego słowa

Wygląda na to, że mój SearchVectorField nie przechowuje konfiguracji wyszukiwania podanej w produkcji, mimo że jest w inscenizacji i dev, i wydaje się, że jest to coś z wersji (mało prawdopodobne, biorąc pod uwagę różnicę wersji i działało to również na 9.3 w inscenizacji/dev) lub fakt, że produkcja odbywa się na RDS zamiast na serwerze lokalnym.

Używam niestandardową konfigurację dla wyszukiwania pełnotekstowego o nazwie unaccent, który wygląda tak:

 Token  |  Dictionaries  
-----------------+----------------------- 
asciihword  | english_stem 
asciiword  | english_stem 
email   | simple 
file   | simple 
float   | simple 
host   | simple 
hword   | unaccent,english_stem 
hword_asciipart | english_stem 
hword_numpart | simple 
hword_part  | unaccent,english_stem 
int    | simple 
numhword  | simple 
numword   | simple 
sfloat   | simple 
uint   | simple 
url    | simple 
url_path  | simple 
version   | simple 
word   | unaccent,english_stem 

Unaccent jest zainstalowany w obu środowiskach i działa w obu środowiskach.

Jestem przechowywania danych wyszukiwania w django.contrib.postgres.search.SearchVectorField na moim Writer modelu

class Writer(models.Model): 
    #... 
    search = SearchVectorField(blank=True) 

tej kolumnie jest aktualizowana z poniższej wyszukiwarki Vector:

writer_search_vector = (SearchVector('first_name', 'last_name', 'display_name', 
            config='unaccent', weight='A') + 
         SearchVector('raw_search_data', config='unaccent', weight='B')) 

przez następującym stwierdzeniem, czyli okresowo:

Writer.objects.update(search=search_utils.writer_search_vector) 

I, z jakiegoś powodu, konfiguracja jest przechowywana pomyślnie na moim serwerze pomostowym i w dev, ale nie w produkcji. Na przykład, kod ten zwraca te same wyniki we wszystkich środowiskach:

In [3]: Writer.objects.annotate(searchy=SearchVector('last_name')).filter(searchy='kostenberger') 
Out[3]: <QuerySet []> 
In [4]: Writer.objects.annotate(searchy=SearchVector('last_name', config='unaccent')).filter(searchy='kostenberger') 
Out[4]: <QuerySet [<Writer: Andreas J. Köstenberger>, <Writer: Margaret Elizabeth Köstenberger>]> 

Ale w inscenizacji, pojawia się następujący wynik poprawny, jeśli mogę użyć zapisanego Vector:

In [5]: Writer.objects.filter(search='kostenberger') 
Out[5]: <QuerySet [<Writer: Andreas J. Köstenberger>, <Writer: Margaret Elizabeth Köstenberger>]> 

podczas produkcji, przeciwko RDS instancja, pojawia się następujący, nieprawidłowy wynik:

In [5]: Writer.objects.filter(search='kostenberger') 
Out[5]: <QuerySet []> 

i jeszcze w produkcji nadal, unaccent prace ale english_stem nie, że będzie ona zgodna z wersją wynikała tekstu (poniżej), ale nie wersji oryginalnej (powyżej):

In [6]: Writer.objects.filter(search='kostenberg') 
Out[6]: <QuerySet [<Writer: Margaret Elizabeth Köstenberger>, <Writer: Andreas J. Köstenberger>]> 

Należy pamiętać, że tabele bazy danych dla pisarza w dwóch środowiskach są identyczne dla tego testu.

Jakieś pomysły, dlaczego przechowywany wektor nie działa w produkcji z poprawną konfiguracją, a jeśli utworzę wektor w locie, zadziała?

Odpowiedz

2

W Postgresie RDS nie można zmienić parametru default_text_search_config. Tak więc musisz skonfigurować wyszukiwanie tekstu przy każdym zapytaniu:

from django.contrib.postgres.search import SearchRank, SearchQuery 
… 
search_query = SearchQuery(value='kostenberger', config='unaccent') 
Writer.objects.filter(search=search_query) 
+1

To było to! Dzięki, David Eyk! Zapytanie nie było ustawione z poprawną konfiguracją, a ja skupiłem się na samym tsvector. – ryanmrubin