django模糊搜索功能

在网站弄了一个网站搜索函数,搜索与名字匹配。
举个例子:数据中心有个名字叫民营发展企业大厦,但如果我输入民企,那么搜索不到信息,必须要输入民或者民营等
def search(request,pIndex = 1):
   search_word = request.GET.get('wd', '')
   building_result = Building.objects.filter(Q(name__contains=search_word))# __contains= 部分匹配
   coperation_result = Corporation.objects.filter(Q(name__contains=search_word))
   tmp_content_list = set()
   if building_result:
       tmp_content_list = set(building_result)

   # 最后将符合条件的文章标题模型和文章内容模型合并返回
   info_list = set()
   if coperation_result:
       info_list = set(coperation_result)

   # 在从文章标题模型中查找出最终汇总的模型返回
   search_result_set = info_list.union(tmp_content_list)
   search_result = list(search_result_set)

   #分页
   page = Paginator(search_result, 10)  # 以每页10条数据分页
   page_num = request.GET.get('page',1)
   page_of_search = page.get_page(page_num)
   maxpages = page.num_pages  # 获取最大页数

   plist = page.page_range  # 获取页码列表信息

   context = {'search_word':search_word,  'search_result':search_result,'search_result_count':len(search_result),'plist':plist,
              'page_of_search':page_of_search,'maxpages':maxpages,}
   return render(request, 'web/search.html',context)


我想要把它修改成输入民企也能搜索到民营发展企业大厦的程度

参考GPT和自己的思路,可以考虑使用Q对象的and和or方法进行多条件搜索,这样就可以实现输入民企也能搜索到民营发展企业大厦的效果。

例如,以下代码可以搜索名称中包含“民”和“企”的建筑和公司信息:

from django.db.models import Q

def search(request,pIndex = 1):
   search_word = request.GET.get('wd', '')
   building_result = Building.objects.filter(Q(name__contains='民') & Q(name__contains='企'))
   coperation_result = Corporation.objects.filter(Q(name__contains='民') & Q(name__contains='企'))
   tmp_content_list = set()
   if building_result:
       tmp_content_list = set(building_result)

   # 最后将符合条件的文章标题模型和文章内容模型合并返回
   info_list = set()
   if coperation_result:
       info_list = set(coperation_result)

   # 在从文章标题模型中查找出最终汇总的模型返回
   search_result_set = info_list.union(tmp_content_list)
   search_result = list(search_result_set)

   #分页
   page = Paginator(search_result, 10)  # 以每页10条数据分页
   page_num = request.GET.get('page',1)
   page_of_search = page.get_page(page_num)
   maxpages = page.num_pages  # 获取最大页数

   plist = page.page_range  # 获取页码列表信息

   context = {'search_word':search_word,  'search_result':search_result,'search_result_count':len(search_result),'plist':plist,
              'page_of_search':page_of_search,'maxpages':maxpages,}
   return render(request, 'web/search.html',context)

如果你希望在搜索中实现模糊匹配,可以使用Django的Q对象中的icontains操作符。该操作符可以进行大小写不敏感的模糊匹配。

修改你的search函数,将__contains替换为__icontains:

from django.db.models import Q

def search(request,pIndex = 1):
   search_word = request.GET.get('wd', '')
   building_result = Building.objects.filter(Q(name__icontains=search_word))
   coperation_result = Corporation.objects.filter(Q(name__icontains=search_word))
   tmp_content_list = set()
   if building_result:
       tmp_content_list = set(building_result)

   # 最后将符合条件的文章标题模型和文章内容模型合并返回
   info_list = set()
   if coperation_result:
       info_list = set(coperation_result)

   # 在从文章标题模型中查找出最终汇总的模型返回
   search_result_set = info_list.union(tmp_content_list)
   search_result = list(search_result_set)

   #分页
   page = Paginator(search_result, 10)  # 以每页10条数据分页
   page_num = request.GET.get('page',1)
   page_of_search = page.get_page(page_num)
   maxpages = page.num_pages  # 获取最大页数

   plist = page.page_range  # 获取页码列表信息

   context = {'search_word':search_word,  'search_result':search_result,'search_result_count':len(search_result),'plist':plist,
              'page_of_search':page_of_search,'maxpages':maxpages,}
   return render(request, 'web/search.html',context)

这样,当用户输入民企时,也能搜索到包含民营或企业等相关内容的记录。

使用Django中的Q对象中的OR运算符来实现模糊搜索呢?


from django.db.models import Q

def search(request, pIndex=1):
    search_word = request.GET.get('wd', '')
    building_result = Building.objects.filter(Q(name__icontains=search_word) | Q(name__icontains=search_word.replace('民', '')))
    coperation_result = Corporation.objects.filter(Q(name__icontains=search_word) | Q(name__icontains=search_word.replace('民', '')))

    # 省略其他代码

该回答引用GPTᴼᴾᴱᴺᴬᴵ
您可以考虑使用 Django 的 Q 对象进行模糊查询,同时将输入的搜索词进行拆分,将拆分后的每个词都作为模糊查询的条件,最后将查询结果合并返回即可。例如:

from django.db.models import Q

def search(request,pIndex = 1):
    search_word = request.GET.get('wd', '')
    search_words = search_word.split(' ')  # 拆分搜索词
    query = Q()
    for word in search_words:
        query |= Q(name__icontains=word)  # 多个 Q 对象进行或操作
    building_result = Building.objects.filter(query)
    coperation_result = Corporation.objects.filter(query)
    ...


其中,Q 对象可以进行逻辑运算,如 &、|、~ 等操作符进行与、或、非操作,这里使用 | 进行或操作,即表示任意一个词匹配即可。同时,将 __contains 改为 __icontains 可以进行大小写不敏感的模糊查询。这样就可以实现输入民企也能搜索到民营发展企业大厦的效果。

您可以在Django中使用Q对象和__icontains查询条件来实现模糊搜索功能,例如:

from django.db.models import Q
from .models import Building

def search_building(request):
    query = request.GET.get('q')
    results = Building.objects.filter(Q(name__icontains=query) | Q(description__icontains=query))
    return render(request, 'search_results.html', {'results': results})

在这个例子中,我们使用Q对象将两个查询条件组合起来,并使用__icontains查询条件来进行模糊匹配。这样,当用户输入"民企"时,如果建筑名称或描述中包含"民企"的字符,则都会被检索到。

注意,这个例子只是一个简单的示例,您可能需要根据自己的具体需求来对查询条件进行调整。同时,为了提高搜索性能,您也可以考虑使用全文搜索引擎,例如Elasticsearch或Solr。

该回答引用ChatGPT

你可以考虑使用模糊查询(fuzzy search)来实现更加灵活的搜索,模糊查询允许在查询时使用通配符,如星号(*)或百分号(%)来代替任何字符,以增加搜索的宽容性。在 Django ORM 中,你可以使用 "icontains" 来进行不区分大小写的模糊查询,如下所示:


building_result = Building.objects.filter(name__icontains=search_word)
coperation_result = Corporation.objects.filter(name__icontains=search_word)

使用 "icontains" 代替 "contains" 可以让 Django 在搜索时忽略大小写和字符顺序。例如,当你搜索 "民企" 时,"民营发展企业大厦" 将会被匹配到,因为它包含 "民" 和 "企" 两个字符。

另外,如果你需要实现更加高级的模糊搜索,可以考虑使用第三方的搜索引擎库,例如 Elasticsearch 或 Solr 等。这些库支持更加灵活的搜索功能,例如基于词汇相似度的搜索、多语言支持、分页和高亮显示等功能。

可以使用iregex正则表达匹配处理:


def search(request,pIndex = 1):
   search_word = request.GET.get('wd', '')
   building_result = Building.objects.filter(Q(name__iregex=r'正则表达式'))# __iregex= 不区分大小写的正则表达式匹配
   coperation_result = Corporation.objects.filter(Q(name__iregex=r'正则表达式'))
   # ... 此处省略其他代码

具体可参照文档中有关不区分大小写的正则表达式匹配的说明: