如何在多个字段上使用 SearchHeadline 和 SearchVector

发布于 2025-01-11 15:26:40 字数 1907 浏览 0 评论 0原文

我需要一个搜索多个字段并返回一个突出显示匹配单词的“标题”。我的理解是 SearchVector 是跨多个字段搜索的合适选择。但我见过的所有 SearchHeadline 示例都只使用一个字段!将 SearchHeadline 与多个字段结合使用的最佳方式是什么?例如,这有效:

return (
    Author.objects
    .annotate(search_vectors=SearchVector('name', 'location'), )
    .filter(search_vectors=SearchQuery(search_string))
)

简单。所以下一步是添加 SearchHeadline...这是我的猜测,但它会导致 PostgreSQL 中出现错误:

return (
    Author.objects
    .annotate(search_vectors=SearchVector('name', 'location'), )
    .annotate(headline=SearchHeadline(
        SearchVector('name', 'location'),
        SearchQuery(search_string),
        start_sel='<strong>', stop_sel='</strong>'))
    .filter(search_vectors=SearchQuery(search_string))
)

错误:

Traceback (most recent call last):
  File "/vagrant/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
psycopg2.errors.UndefinedFunction: function ts_headline(tsvector, tsquery, unknown) does not exist
LINE 1: ...app_author"."location", '')) AS "search_vectors", ts_headlin...
                                                             ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

SearchVector() 不是有效的表达式吗?

使用 Concat() 可以完成工作,但这不允许我利用 ts_vector 的内置索引功能。对我来说这感觉像是一个黑客解决方案。

return (
    Author.objects
    .annotate(search_vectors=SearchVector('name', 'location'), )
    .annotate(headline=SearchHeadline(
        Concat(F('name'), Value(' '), F('location')),
        SearchQuery(search_string),
        start_sel='<strong>', stop_sel='</strong>'))
    .filter(search_vectors=SearchQuery(search_string))
)

最好的方法是什么?

I need a search that searches multiple fields and returns a "headline" which highlights the matching words. My understanding is that SearchVector is the appropriate choice for searching across multiple fields. But all of the examples I've seen of SearchHeadline use only a single field! What's the best way to use SearchHeadline with multiple fields? For example, this works:

return (
    Author.objects
    .annotate(search_vectors=SearchVector('name', 'location'), )
    .filter(search_vectors=SearchQuery(search_string))
)

Easy. So the next step is to add SearchHeadline... Here was my guess, but it causes an error in PostgreSQL:

return (
    Author.objects
    .annotate(search_vectors=SearchVector('name', 'location'), )
    .annotate(headline=SearchHeadline(
        SearchVector('name', 'location'),
        SearchQuery(search_string),
        start_sel='<strong>', stop_sel='</strong>'))
    .filter(search_vectors=SearchQuery(search_string))
)

Error:

Traceback (most recent call last):
  File "/vagrant/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
psycopg2.errors.UndefinedFunction: function ts_headline(tsvector, tsquery, unknown) does not exist
LINE 1: ...app_author"."location", '')) AS "search_vectors", ts_headlin...
                                                             ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

Is SearchVector() not a valid expression?

Using Concat() gets the job done, but this doesn't allow me to leverage the built in indexing capabilities of a ts_vector. It feels like a hack solution to me.

return (
    Author.objects
    .annotate(search_vectors=SearchVector('name', 'location'), )
    .annotate(headline=SearchHeadline(
        Concat(F('name'), Value(' '), F('location')),
        SearchQuery(search_string),
        start_sel='<strong>', stop_sel='</strong>'))
    .filter(search_vectors=SearchQuery(search_string))
)

What's the best way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晚雾 2025-01-18 15:26:40

我看不到任何使用 tsvector 的可能性。
查看文档。

ts_headline 使用原始文档,而不是 tsvector 摘要,因此它可能很慢,应谨慎使用。

https://www.postgresql.org/docs/current/textsearch-controls。 html

一般来说,您的解决方法是(独特的)解决方案
:-)

I don't see any possibility to use a tsvector.
Have a look in the documentation.

ts_headline uses the original document, not a tsvector summary, so it can be slow and should be used with care.

https://www.postgresql.org/docs/current/textsearch-controls.html

in general your workaround is the (unique) solution
:-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文