0

GIN 인덱스를 사용하는 전체 텍스트 검색을 위해 장고보기에서 적절한 쿼리를 작성하는 데 도움이 필요합니다. 나는 꽤 큰 데이터베이스 (~ 400k 라인)를 가지고 있으며, 3 개의 필드에서 전체 텍스트 검색을 할 필요가있다. django docs search을 사용하려고했는데 이것은 GIN BEFORE 코드입니다. 작동하지만 모든 필드를 검색하는 데 6 초 이상 걸립니다. 다음으로 검색 속도를 높이기 위해 GIN 색인을 구현하려고했습니다. 이미 그것을 구축하는 방법에 대해 많은 질문이 있습니다. 하지만 제 질문은 - 검색을 위해 GIN 인덱스를 사용할 때 뷰 쿼리가 어떻게 바뀌나요? 어떤 필드를 검색해야합니까?

models.py보기에서 전체 텍스트 검색 + GIN 사용 (장고 1.11)

class Product(TimeStampedModel): 
product_id = models.AutoField(primary_key=True,) 
shop = models.ForeignKey('Shop', to_field='shop_name') 
brand = models.ForeignKey('Brand', to_field='brand_name') 
title = models.TextField(blank=False, null=False) 
description = models.TextField(blank=True, null=True) 

views.py

def get_cosmetic(request): 
if request.method == "GET": 
    pass 
else: 
    search_words = request.POST.get('search') 
    search_vectors = SearchVector('title', weight='B')+ SearchVector('description', weight='C') + SearchVector('brand__brand_name', weight='A') 

    products = Product.objects.annotate(search = search_vectors, rank=SearchRank(search_vectors, search))\ 
     .filter(search=search_words).order_by('-rank') 

    return render(request, 'example.html', {"products": products}) 

GIN 후 : GIN 전에


models.py

class ProductManager(models.Manager): 
def with_documents(self): 
    vector = pg_search.SearchVector('brand__brand_name', weight='A') +\ 
      pg_search.SearchVector('title', weight='A')+\ 
      pg_search.SearchVector('description', weight='C') 
    return self.get_queryset().annotate(document=vector) 


class Product(TimeStampedModel): 
product_id = models.AutoField(primary_key=True,) 
shop = models.ForeignKey('Shop', to_field='shop_name') 
brand = models.ForeignKey('Brand', to_field='brand_name') 
title = models.TextField(blank=False, null=False) 
description = models.TextField(blank=True, null=True) 

search_vector = pg_search.SearchVectorField(null=True) 

objects = ProductManager() 

class Meta: 
    indexes = [ 
     indexes.GinIndex(fields=['search_vector'], name='title_index') 
    ] 

#update search_vector every time the entry updates 
def save(self, *args, **kwargs): 
    super().save(*args, **kwargs) 
    if 'update_fields' not in kwargs or 'search_vector' not in kwargs['update_fields']: 
     instance = self._meta.default_manager.with_documents().get(pk=self.pk) 
     instance.search_vector = instance.document 
     instance.save(update_fields=['search_vector']) 

views.py

def get_cosmetic(request): 
if request.method == "GET": 
    pass 

else: 
    search_words = request.POST.get('search')  
    products = ????????? 
    return render(request, 'example.html', {"products": products}) 

답변

0

내 자신의 질문에 대답 :

products = Product.objects.annotate(rank=SearchRank(F('search_vector'), search_words)) 
          .filter(search_vector=search_words) 
          .order_by('-rank') 


이것은 당신이 당신의 색인 필드를 검색 할 뜻을 -에 내 경우 search_vector 들.
이 또한 내가 그래서 지금 난 그냥 with_documents() 사용자 정의 ProductManager의 사용자 지정 기능입니다

products = Product.objects.with_documents(search_words) 

를 사용할 수 ProductManager() 클래스 내 코드를 조금 변경되었습니다(). 이 변경의 제조법은 here (page 30)입니다.


1) 필드에 점수가있는 search_vector를 생성합니다. 점수가 큰 필드는 결과 정렬에서 더 높은 위치를 얻습니다.
1) 그것은 정렬되지 않습니다 :
2) ORM 장고
3) 업데이트 GIN 인덱스를 통해 전체 텍스트 검색 모델의 인스턴스가이 코드가 할 dosn't 무엇

변경 될 때마다위한 GIN 인덱스를 생성 질의되는 하위 문자열의 관련성에 따라 Possible solution.

희망이 장고에서 약간 복잡한 전체 텍스트 검색 누군가 도움이 될 것입니다.