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})