Мне нужна помощь в создании правильного запроса в представлении django для полнотекстового поиска с использованием индекса GIN. У меня довольно большая база данных (~ 400 тысяч строк), и мне нужно выполнить полнотекстовый поиск по 3 полям из нее. Пытался использовать поиск документов django, и это код ДО ДЖИН. Это работает, но поиск по всем полям занимает 6+ секунд. Затем я попытался реализовать индекс GIN для ускорения мой поиск. Уже есть много вопросов, как его построить. Но у меня вопрос: как меняется запрос представления при использовании индекса GIN для поиска? В каких полях мне следует выполнять поиск?
До GIN:
models.py
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:
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})
search_vector
напрямуюinstance.search_vector
? Я не могу понять, пожалуйста, объясните мне. спасибо - person achilles   schedule 03.04.2019.save(update_fields=['search_vector'])
может обновлять только выбранные поля и повышать производительность. Если я правильно понимаю вопрос. - person Chiefir   schedule 03.04.2019instance = self._meta.default_manager.with_documents().get(pk=self.pk) instance.search_vector = instance.document
Почему мы не можем назначать так:instance.search_vector = SearchVector(...)
- person achilles   schedule 03.04.2019