Django文本搜索与部分句子匹配

时间:2012-07-21 16:42:09

标签: django full-text-search

我正在构建一个网站,我想在其中实现文本搜索某些对象的标题和描述。因为我将拥有少量的物品(约500份文件),所以我不会考虑Haystack等等。

我只需要2个功能:

  • 能够优先考虑标题上的匹配项目(具有某种权重)。
  • 允许部分匹配句子。例如,如果我搜索“冰淇淋”,​​也可以获得“冰”和“奶油”的结果。

我调查了django-watsondjango-full-text-search,但我不确定他们是否允许部分匹配。 有什么想法吗?

6 个答案:

答案 0 :(得分:3)

您的网站每秒有多少次点击?每个文件,有多少数据存储?

如果我们谈论的是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 ) 

您曾考虑过此选项吗?

小心:

  • 此方法不会将标题优先于描述
  • 结果中仅显示“所有字词”匹配。

答案 1 :(得分:3)

作为django-watson的创建者,我可以确认,通过一些数据库后端,它允许部分匹配。具体来说,在MySQL和PostgreSQL上,它允许前缀匹配,这是从单词开头的部分匹配。

在wiki上查看此数据库比较页面:

https://github.com/etianen/django-watson/wiki/Database-support

答案 2 :(得分:2)

查看this文章。它包含有关您要执行的操作的信息。

同时查看Haystack。飞快移动似乎是一个不错的选择。

答案 3 :(得分:1)

使用新的full-text search in 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

Refer to the Postgres docs for the ts_query syntax

然后您可以在如下的查询中使用它:

vector = SearchVector(  
    'first_name',
    'last_name',
    'email',
    config='simple')
query = PrefixedPhraseQuery(query, config='simple')
queryset = queryset\
    .annotate(vector=vector)\
    .filter(vector=query)

你也可以写一个startswith查询,参考SearchVectorExact的实现。

答案 4 :(得分:0)

我在我的项目中使用了Apache Solr,它非常好并且有很多文档。并检查sunburntpysolrsolrpy

答案 5 :(得分:0)

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')