在全文搜索中按排名排序的正确方法?

问题描述

我正在尝试通过 postgresql 中的多个相关模型字段实现全文搜索

我的想法是使用 tsvector 将我需要搜索的所有字段放入一个连接的 to_tsvector(array_to_string(array[field1,field2,...],' ') 中,然后将其与实际搜索查询中的 tsquery 词素匹配。

我得到的 tsquery 是这样的:

select to_tsquery(string_agg(lexeme || ':*',' | ' order by positions)) as query
from unnest(to_tsvector('actual search query')).

为了匹配,我使用了 @@ 运算符:select ... from ... where mytsvector @@ query

它似乎对我来说工作正常,但我注意到它并没有真正将行从最高匹配结果排序到最低匹配结果。因此,我尝试使用 ts_rank_cd 函数获取分数,然后添加 order by score DESC

然而,我得到的分数几乎总是 00.1,很少有其他东西(例如 0.93251 等)。但是,即使那些高于 0.1 的分数似乎并不比许多其他具有 0.1 甚至 0 分数的人更好。这让我觉得我的排名方式不对。

我认为,通过连接我需要进行搜索的所有列,我可以同时为来自不同列的匹配项获得不错的排序搜索结果

我将列与进一步匹配连接起来的想法至少可行吗?或者有更好的方法来做到这一点?


这是我的实际查询(已添加排名)

 with search as (
    select to_tsquery(string_agg(lexeme || ':*',' | ' order by positions)) as query
    from unnest(to_tsvector('my search query'))
 )
 select
    meeting.*,business.company as member_company,companydepartment.name as sp_company,ts_rank_cd(
         to_tsvector(array_to_string(array[
            "user".firstname,"user".lastname,"user".email,business.company,companydepartment.name,meeting.url,meeting.status,meeting.id::text
        ],' ')),query
    ) as score
    from
        search,meeting
        join project on project.id = meeting.projectid
        left join business on business.id = project.businessid

        left join salesprofile on salesprofile.id = meeting.salesprofileid
        left join companydepartment on salesprofile.id = companydepartment.salesprofileid

        join "user" on "user".id = business.userid or "user".id = salesprofile.userid
    where
        to_tsvector(array_to_string(array[
            "user".firstname,' '))
        @@ query
    group by
        search.query,business.userid,meeting.id,salesprofile.userid,"user".firstname,"user".email
    order by score desc;

我的排名是否正确?如果没有,那么我的错误在哪里以及如何解决


PS:我想要实现的例子是这样的:

  • 我收到一个搜索查询,其中可能包含一个或多个字词、网址、数字等。

  • 我需要将这些词拆分成有意义的部分(词素),然后找到与我的搜索查询最匹配的行。

例如,我可以尝试按 meeting.status"user".emailbusiness.company 进行搜索,并使用查询 accepted email@email.com GoogleFacebook Rejected email+2@email.com(以任意顺序)字)。我想首先获得符合所有三个条件的结果,然后是至少符合其中 2 个条件的结果,然后是至少符合其中一个条件的结果。

但是,通过这样的搜索查询和上面的 sql,我得到了一些随机排序(例如,结果的第一行可能只是状态为 accepted 的会议,第二行可能是状态为 {{1} 的会议} 和公司名称 accepted 等等,尽管 Google)。


我还尝试在排名函数order by score 语句中执行 setweight 时使用 to_tsvector,如下所示,这稍微改变了我的排名,但并没有真正改变这是我所期望的。

where

即使我将 ts_rank_cd( to_tsvector(array_to_string(array[ meeting.url,' ') || setweight(to_tsvector('english',coalesce(meeting.status,'')),'A') || setweight(to_tsvector('english',coalesce(business.company,'B') || setweight(to_tsvector('english',coalesce(companydepartment.name,'B') || setweight(to_tsvector(coalesce("user".email,coalesce("user".firstname,'C') || setweight(to_tsvector('english',coalesce("user".lastname,'C') ),query ) as score 置于权重 meeting.status,它的匹配度也没有比其他匹配高 A


我的方法正确吗?如果不是,如何更好地实现预期的功能?如果是,那么为什么我没有得到正确的(在我看来)排名?


PPS:我不能使用 status 或其他扩展。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...