سرمایه گذاری متفاوت در سال نو 🍎🌱 ۳۵٪ تخفیف نوروزی ➕ حضور رایگان در مسترمایند نخبگان صنعت نرم‌افزار 💻✅
۰ ثانیه
۰ دقیقه
۰ ساعت
۳ Mohsen Azizi
ترکیب کردن TrigramSimilarity و SearchRank برای جستجوی پیشرفته‌تر در دیتابیس(Full text search)
محمدعلی رضا حل شده توسط محمدعلی رضا
from django.contrib.postgres.search import SearchVector, SearchQuery, SearchRank, TrigramSimilarity
def post_search(request):
    form = SearchForm()
    if 'query' in request.GET.keys():
        form = SearchForm(request.GET)
        if form.is_valid():
            cleaned_data = form.cleaned_data
            query = cleaned_data['query']
            search_vector = SearchVector('title', weight='A') + SearchVector('body', weight='B')
            search_query = SearchQuery(query)
            posts = Post.published.annotate(
                similarity=TrigramSimilarity(
                    'title', query
                )
            ).filter(similarity__gt=0.1).annotate(
                rank=SearchRank(search_vector, search_query)
            ).filter(rank__gte=0.3).order_by('-rank')
            return render(
                request, template_name='blog/post_search.html',
                context={'posts': posts, 'form': form}
            )
    return render(request, template_name='blog/post_search.html', context={'form': form})

سلام 

کدی که نوشتم مربوط به سرچ داخل دیتابیس با استفاده از full text search با استفاده از postgresql است

مشکلی که من دارم اینه که 

annotate(
                similarity=TrigramSimilarity(
                    'title', query
                ).filter(similarity__gt=0.1)

این قسمت از کد فقط مواردی رو از دیتابیس بر میگردونه که title پست‌ها با مقدار query برابر یا مشابه query باشن

annotate(
                rank=SearchRank(search_vector, search_query)
            ).filter(rank__gte=0.3).order_by('-rank')

و این قسمت کد فقط مواردی رو از دیتابیس بر میگردنه که مقدار search_vector دقیقا برابر با search_query باشه(و مقادیری که واکشی میشن از دیتابیس رتبه بندی هم میکنه بر اساس تعداد تکرار search_query در search_vector)

 

زمانی که این دو قسمت با هم ترکیب میشن ما باید حتما دقیق سرچ کنیم وگرنه مقداری رو بر نمیگردونه

از نظر خودم مشکل بر میگرده به قسمت دوم کد چون باید مقدار search_query رو دقیق وارد کنیم

ولی ما تو قسمت اول کد از روی مقدار query مقدار search_query رو ساختیم

 

میخواستم ببینم آیا راه حلی هست که دقیق سرچ نکنیم بتونیم موارد مشابه رو از دیتابیس واکشی کنیم و رتبه بندی هم بکنیم ؟

 

خیلی بد توضیح دادم امیدوارم که منظورم رو رسونده باشم

ممنون میشم راهنمایی کنید

سلاااااااااااااااااام محسن جان

خیلی سرچ و فکر کردم. به نتیجه ای نرسیدم.

به استاد ایمیل میزنم که ایشون جوابت رو بدن.

لطفا پروژه ات یا لینک ریپو گیت لب یا گیت هاب ات پروژه ات هم بذارم که راحتتر بتونیم کمکت کنیم.

 

بهترین پاسخ
محمدعلی رضا ۰۲ مهر ۱۴۰۰، ۱۶:۵۲

محسن جان

ببین این جواب کمکت میکنه؟

Combine trigram with ranked searching in django 1.10

محمدعلی رضا ۰۲ مهر ۱۴۰۰، ۱۷:۳۴

احتمالا جواب قبلی ای که گفتم کمکت نکنه.

اگر کاربر به انگلیسی سرچ میکنه که مساله ای نداری اگر به زبان دیگه ای مثل فارسی سرچ میکنه احتمالا باید کارهای زیر رو انجام بدی:

احتمالا باید config ات رو عوض کنی:

Changing the search configuration

 

و لازمه که configuration درست همراه با parser و dictionary لازم رو تو postgres ات داشته باشی. یا بسازی.

12.7. Configuration Example

12.5. Parsers

12.6. Dictionaries

 

البته خب همیشه ابزارهای آماده ای هست که گوگل بهمون کمک میکنه پیداشون کنیم.

من تو گوگل سرچ کردم:

postgres persian text search configuration

 

و به جواب زیر رسیدم:

How to use full text search in Persian using Postgresql?

که میگه یا از کانفیگ simple استفاده کن یا از extension ای که معرفی کرده.

 

لطفا این راه حلی که گفتم رو تست کن و نتیجه اش رو بگو.

این موضوعی هم که سوال کردی بیشتر مربوط به دیتابیس، بچه‌های دیتا و DBA بود. و از زمینه کاری بکند خارج عه. البته شاید واقعا نشه برای برنامه نویس محدوده ای مشخص کرد. (نمیدونم بگیم برنامه نویس یا گیک؟!)

محمدعلی رضا ۰۲ مهر ۱۴۰۰، ۱۸:۱۷