Django 中的 PostgreSQL 文本搜索未按预期工作

PostgreSQL text search in Django not working as expected

我正在为 API 到 return 请求时对象的属性实现搜索功能。到目前为止,我已经尝试使用 Full Text Search,它是可用的,但它有这些烦人的事情:必须正确拼写单词才能 returned 和部分搜索,例如 "appl" 而不是 "apple",将不起作用。我也试过八卦相似度,但长句失败了。如何在 Django 中实现既准确又模糊的搜索功能?

有效

这行不通

这是我的views.py

from django.shortcuts import render
from rest_framework.response import Response
from rest_framework import status
from rest_framework.decorators import api_view
from .models import Object_Locations
from .serializers import Object_LocationsSerializer
from django.contrib.postgres.search import SearchVector, SearchQuery


def index(request):
   return render(request, 'main/base.html', {})

@api_view(['GET',])
def LocationsList(request):
    if request.method == 'GET':
        vector = SearchVector('name', 'desc', 'catergory')
        query = request.GET.get('search')

        if query:
            locations = Object_Locations.objects.annotate(search=vector,).filter(search=SearchQuery(query))
        else:
            locations = Object_Locations.objects.all()

        serializer = Object_LocationsSerializer(locations, many=True)
        return Response(serializer.data)

来自 SearchQuery 文档:

SearchQuery translates the terms the user provides into a search query object that the database compares to a search vector. By default, all the words the user provides are passed through the stemming algorithms, and then it looks for matches for all of the resulting terms.

If search_type is 'plain', which is the default, the terms are treated as separate keywords. If search_type is 'phrase', the terms are treated as a single phrase. If search_type is 'raw', then you can provide a formatted search query with terms and operators.

在上面的代码中,带有搜索短语 "a blac husky"SearchQuery 被翻译成 SQL 代码喜欢:

... @@ plainto_tsquery('a blac husky') ...

因此,如果您想获得包含相似搜索词组的结果,可以组合查询词:

from django.contrib.postgres.search import SearchQuery, SearchVector
from django.shortcuts import render
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response

from .models import Object_Locations
from .serializers import Object_LocationsSerializer


def index(request):
return render(request, 'main/base.html', {})


@api_view(['GET',])
def LocationsList(request):
    if request.method == 'GET':
        vector = SearchVector('name', 'desc', 'catergory')
        query_terms = request.GET.get('search')
        query_raw = ' | '.join(query_terms.split())
        query = SearchQuery(query_raw, search_type='raw')
        if query.value:
            locations = Object_Locations.objects.annotate(search=vector).filter(search=query)
        else:
            locations = Object_Locations.objects.all()
        serializer = Object_LocationsSerializer(locations, many=True)
        return Response(serializer.data)

在上面的代码中,带有搜索短语 "a blac husky"SearchQuery 被翻译成 SQL 代码喜欢:

... @@ plainto_tsquery('a | blac | husky') ...

可以按照我链接的文档中的描述使用逻辑运算来组合 SearchQuery。

如果您想进一步深入,可以阅读我写的一篇关于该主题的文章

"Full-Text Search in Django with PostgreSQL"