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。
如果您想进一步深入,可以阅读我写的一篇关于该主题的文章:
我正在为 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。
如果您想进一步深入,可以阅读我写的一篇关于该主题的文章: