我正在构建一个站点,我想在其中实现对某些对象的标题和描述的文本搜索。由于我的对象数量很少(约 500 个文档),我不考虑 Haystack 之类的。
我只需要 2 个功能:
- 能够将标题上的匹配优先于描述(具有某种权重)。
- 允许句子的部分匹配。例如,如果我搜索“冰淇淋”,也会得到“冰”和“奶油”的结果。
我研究了django-watson和django-full-text-search但我不确定它们是否允许部分匹配。有任何想法吗?
我正在构建一个站点,我想在其中实现对某些对象的标题和描述的文本搜索。由于我的对象数量很少(约 500 个文档),我不考虑 Haystack 之类的。
我只需要 2 个功能:
我研究了django-watson和django-full-text-search但我不确定它们是否允许部分匹配。有任何想法吗?
作为 django-watson 的创建者,我可以确认,对于某些数据库后端,它允许部分匹配。具体来说,在 MySQL 和 PostgreSQL 上,它允许前缀匹配,即从单词的开头部分匹配。
在 wiki 上查看这个数据库比较页面:
https://github.com/etianen/django-watson/wiki/Database-support
您的网站有多少次点击?每个文档,有多少个数据存储?
如果我们谈论的是 500 个文档并且每分钟点击数很少,那么 django api 就足够了:
q = None
for word in search_string.split():
q_aux = Q( title__icontains = word ) | Q( description__icontains = word )
q = ( q_aux & q ) if bool( q ) else q_aux
result = Document.objects.filter( q )
你有没有考虑过这个选项?
当心:
使用新的全文搜索django.contrib.postgres
作为起点,可以扩展SearchQuery
以创建一个版本来处理最终单词的部分部分的搜索:
from psycopg2.extensions import adapt
from django.contrib.postgres.search import SearchQuery
class PrefixedPhraseQuery(SearchQuery):
"""
Alter the tsquery executed by SearchQuery
"""
def as_sql(self, compiler, connection):
# Or <-> available in Postgres 9.6
value = adapt('%s:*' % ' & '.join(self.value.split()))
if self.config:
config_sql, config_params = compiler.compile(self.config)
template = 'to_tsquery({}::regconfig, {})'\
.format(config_sql, value)
params = config_params
else:
template = 'to_tsquery({})'\
.format(value)
params = []
if self.invert:
template = '!!({})'.format(template)
return template, params
然后,您可以在这样的查询中使用它:
vector = SearchVector(
'first_name',
'last_name',
'email',
config='simple')
query = PrefixedPhraseQuery(query, config='simple')
queryset = queryset\
.annotate(vector=vector)\
.filter(vector=query)
你也可以写一个startswith
查找,参考SearchVectorExact
.
在更新的 Django 版本中,这变得更加简单。SearchQuery
现在有一种raw
模式可以用来请求前缀查询。
query = SearchQuery("search & term & prefix:*", search_type="raw")
results = Model.objects\
.filter(_search_vector=query)\
.annotate(
rank=SearchRank(
F("_search_vector"),
query,
cover_density=True,
)
)
.order_by("-rank")
哪里_search_vector
是SearchVectorField
, 或 可以在模型上注释。
我在我的项目中使用了Apache Solr,它非常好并且有很多文档。并检查sunburnt、pysolr和solrpy
Django 现在支持全文搜索:Django Full Text Search。
重要提示:似乎这仅适用于 postgres db 后端。
# Example based on Django Docs.
Entry.objects.annotate(
search=SearchVector('title', 'description'),
).filter(search='some_text')
您还可以使用搜索查找
Entry.objects.filter(title__search='Cheese')