网站哪家好,电脑上如何进入wordpress,上海小程序开发报价,游戏软件开发公司简介说到django的全文检索#xff0c;网上基本推荐的都是 haystack whoosh jieba 的方案。 由于我的需求对搜索时间敏感度较低#xff0c;但是要求不能有数据的错漏。 但是没有调试的情况下#xff0c;搜索质量真的很差#xff0c;搞得我都想直接用Like搜索数据库算了。 但是…说到django的全文检索网上基本推荐的都是 haystack whoosh jieba 的方案。 由于我的需求对搜索时间敏感度较低但是要求不能有数据的错漏。 但是没有调试的情况下搜索质量真的很差搞得我都想直接用Like搜索数据库算了。 但是峰回路转还是让我找到几个信息稍微优化了一下搜索结果。
1.haystack
haystack这层我增加了一个模糊搜索即原本的textq’变成了text__contains‘q’。 搜索从原本的的content切换成了contains不再需要完全匹配就能命中。 比如词“下雨”在用content的时候搜“雨”是没办法命中的换成contain之后就可以了。需要搭配第二点中的自定义全量分词默认分词不行。具体原因不知不过应该不是index的问题因为我测试过用默认分词rebuild_index后再切换ChineseAnalyzer而不重新rebuild_index依然可以搜索到结果猜测原因应该是对搜索词的分词但是我就一个字有啥好分词的有懂得大佬麻烦教我一下。
class LynSearchForm(SearchForm):def search(self):if not self.is_valid():return self.no_query_found()if not self.cleaned_data.get(q):return self.no_query_found()# 原设置搜索条件的语句被我替换成下面的语句# sqs self.searchqueryset.auto_query(self.cleaned_data[q]) sqs self.searchqueryset.filter(text__containsself.cleaned_data[q])if self.load_all:sqs sqs.load_all()return sqs我写这篇文章的时间是2023年8月haystack已经进行了大的更新。从原本的views.SearchView 切换到了 generic_views.SearchView。把接口都给换了然后代码里面还是旧的内容各位看官看的时候要注意。
新流程以SearchView为例
form self.get_form(form_class)
self.queryset form.search()
context self.get_context_data({self.form_name: form})get_context_data是django的view的函数所以我们要做的是在form上面做手脚。
2.whoosh jieba
除了上面的操作外还需要对jieba的ChineseAnalyzer进行自定义修改成全量分词。 代码来源 州的先生 大佬写的MrDoc我从中受益良多大家有兴趣可以多多支持
# coding:utf-8
# 文件: chinese_analyzer.py
# 创建者州的先生
# #日期2020/11/22
# 博客地址zmister.comfrom whoosh.compat import u, text_type
from whoosh.analysis.filters import LowercaseFilter
from whoosh.analysis.filters import StopFilter, STOP_WORDS
from whoosh.analysis.morph import StemFilter
from whoosh.analysis.tokenizers import default_pattern
from whoosh.lang.porter import stem
from whoosh.analysis import Tokenizer, Token
from whoosh.util.text import rcompile
import jiebaclass ChineseTokenizer(Tokenizer):使用正则表达式从文本中提取 token 令牌。 rex ChineseTokenizer() [token.text for token in rex(u(hi there 3.141 big-time under_score))][hi, there, 3.141, big, time, under_score]def __init__(self, expressiondefault_pattern, gapsFalse)::param expression: 一个正则表达式对象或字符串默认为 rcompile(r\w(\.?\w)*)。表达式的每一个匹配都等于一个 token 令牌。第0组匹配整个匹配文本用作 token 令牌的文本。如果你需要更复杂的正则表达式匹配处理只需要编写自己的 tokenizer 令牌解析器即可。:param gaps: 如果为 True, tokenizer 令牌解析器会在正则表达式上进行分割而非匹配。self.expression rcompile(expression)self.gaps gapsdef __eq__(self, other):if self.__class__ is other.__class__:if self.expression.pattern other.expression.pattern:return Truereturn Falsedef __call__(self, value, positionsFalse, charsFalse, keeporiginalFalse,removestopsTrue, start_pos0, start_char0, tokenizeTrue,mode, **kwargs)::param value: 进行令牌解析的 Unicode 字符串。:param positions: 是否在 token 令牌中记录 token 令牌位置。:param chars: 是否在 token 中记录字符偏移。:param start_pos: 第一个 token 的位置。例如如果设置 start_pos2, 那么 token 的位置将是 2,3,4,...而非 0,1,2,...:param start_char: 第一个 token 中第一个字符的偏移量。例如, 如果设置 start_char2, 那么文本 aaa bbb 解析的两个字符串位置将体现为 (2,5),(6,9) 而非 (0,3),(4,7).:param tokenize: 如果为 True, 文本应该被令牌解析。# 判断传入的文本是否为字符串如果不为字符串则抛出assert isinstance(value, text_type), %s is not unicode % repr(value)t Token(positions, chars, removestopsremovestops, modemode,**kwargs)if not tokenize:t.original t.text valuet.boost 1.0if positions:t.pos start_posif chars:t.startchar start_chart.endchar start_char len(value)yield telif not self.gaps:# The default: expression matches are used as tokens# 默认情况下正则表达式的匹配用作 token 令牌# for pos, match in enumerate(self.expression.finditer(value)):# t.text match.group(0)# t.boost 1.0# if keeporiginal:# t.original t.text# t.stopped False# if positions:# t.pos start_pos pos# if chars:# t.startchar start_char match.start()# t.endchar start_char match.end()# yield tseglist jieba.cut(value, cut_allTrue)for w in seglist:t.original t.text wt.boost 1.0if positions:t.pos start_pos value.find(w)if chars:t.startchar start_char value.find(w)t.endchar start_char value.find(w) len(w)yield telse:# When gapsTrue, iterate through the matches and# yield the text between them.# 当 gapsTrue, 遍历匹配项并在它们之间生成文本。prevend 0pos start_posfor match in self.expression.finditer(value):start prevendend match.start()text value[start:end]if text:t.text textt.boost 1.0if keeporiginal:t.original t.textt.stopped Falseif positions:t.pos pospos 1if chars:t.startchar start_char startt.endchar start_char endyield tprevend match.end()# If the last gap was before the end of the text,# yield the last bit of text as a final token.if prevend len(value):t.text value[prevend:]t.boost 1.0if keeporiginal:t.original t.textt.stopped Falseif positions:t.pos posif chars:t.startchar prevendt.endchar len(value)yield tdef ChineseAnalyzer(expressiondefault_pattern, stoplistNone,minsize2, maxsizeNone, gapsFalse, stemfnstem,ignoreNone, cachesize50000):Composes a RegexTokenizer with a lower case filter, an optional stopfilter, and a stemming filter.用小写过滤器、可选的停止停用词过滤器和词干过滤器组成生成器。 ana ChineseAnalyzer() [token.text for token in ana(Testing is testing and testing)][test, test, test]:param expression: 用于提取 token 令牌的正则表达式:param stoplist: 一个停用词列表。 设置为 None 标识禁用停用词过滤功能。:param minsize: 单词最小长度小于它的单词将被从流中删除。:param maxsize: 单词最大长度大于它的单词将被从流中删除。:param gaps: 如果为 True, tokenizer 令牌解析器将会分割正则表达式而非匹配正则表达式:param ignore: 一组忽略的单词。:param cachesize: 缓存词干词的最大数目。 这个数字越大词干生成的速度就越快但占用的内存就越多。使用 None 表示无缓存使用 -1 表示无限缓存。ret ChineseTokenizer(expressionexpression, gapsgaps)chain ret | LowercaseFilter()if stoplist is not None:chain chain | StopFilter(stopliststoplist, minsizeminsize,maxsizemaxsize)return chain | StemFilter(stemfnstemfn, ignoreignore,cachesizecachesize)重点是这个 在PS2里面结巴的大佬有提到有新功能11年前的jieba.cut_for_search()也可以试试
然后在whoosh_cn_backend.py里面修改ChineseAnalyzer。
from .chinese_analyzer import ChineseAnalyzer
# from jieba.analyse import ChineseAnalyzerPS:这个jieba自带的ChineseAnalyzer也是我换的如果你第一次搞这个可以参考 https://blog.csdn.net/qiqiyingse/article/details/110299639 PS
1.HayStack As of version 2.4 the views in haystack.views.SearchView are deprecated in favor of the new generic views in haystack.generic_views.SearchView which use the standard Django class-based views which are available in every version of Django which is supported by Haystack. 新代码旧流程可真有你的。
2.CSDN
稍微吐槽下CSDN,STONE大哥的文章里面下面结巴的大佬在评论区有回复结果评论显示的是2条还好我点开看了一下。不然就错过了这么重要的信息。 https://blog.csdn.net/wenxuansoft/article/details/8169842 然后显示的热评是个灌水回答。。 3.其他筛选参数 关于筛选的类型在whoosh_cn_backend.py文件中基本和django的差不多。