N个字以内全文搜索

Ale*_*usa 5 postgresql full-text-search

是否可以创建一个tsquery,当一个单词中找到另一个单词的N个单词时将其匹配?

例如,短语“ 快速的棕色狐狸跳过 ”,我可以使用“其次是”搜索运营商,但只有当我知道究竟有多少话是什么之间我在寻找:

SELECT to_tsquery('simple', 'quick <4> over') @@ to_tsvector('simple', 'quick brown fox jumps over');
Run Code Online (Sandbox Code Playgroud)

但是我可能事先不知道要寻找的词之间有多少个字,我想做些类似的事情:

to_tsquery('simple', 'quick <?4> over')

在这里,我试图指定它可以是以下任意一个:相隔1、2、3或4个字。我似乎无法找到一种方法来对我需要的单词的每个变体都复制原始的“后跟”运算符。

编辑:这必须扩大以适应用户可能创建的任何更大或更复杂的有效tsquery。提供的示例已简化为仅包含相关问题。

Y.K*_*.K. 0

尝试这样的事情:

select
    x.*,
    y.*,
    tsquery_phrase(query1, query2, y) as query_text,
    tsquery_phrase(query1, query2, y) @@ to_tsvector('simple', 'quick brown fox jumps over') as result
from
    (   select
            to_tsquery('simple', 'quick') as query1,
            to_tsquery('simple', 'over') as query2) as x
    cross join generate_series(1, 10) as y
where
    tsquery_phrase(query1, query2, y) @@ to_tsvector('simple', 'quick brown fox jumps over')
Run Code Online (Sandbox Code Playgroud)

另一种尝试:

with

sample_data as (
    select
        x.text,
        x.vector,
        q.id as query_id,
        y,
        tsquery_phrase(q.query1, q.query2, y) as query_text,
        tsquery_phrase(q.query1, q.query2, y) @@ x.vector as result
    from
        (   select
                'quick brown fow jumps over but the duck is swimming under' as text,
                to_tsvector('simple', 'quick brown fow jumps over but the duck swimming under'::text) as vector) as x
        cross join (select
                        1 as id,
                        to_tsquery('simple', 'quick'::text) as query1,
                        to_tsquery('simple', 'over'::text) as query2
                    union all
                    select
                        2 as id,
                        to_tsquery('simple', 'duck'::text) as query1,
                        to_tsquery('simple', 'under'::text) as query2) as q
        cross join generate_series(1, 10) as y
    where
        tsquery_phrase(q.query1, q.query2, y) @@ x.vector
        and y = case q.id when 1 then 4 when 2 then 2 end
)

select
    text
from
    sample_data
group by
    1
having
    count(*) = 2
Run Code Online (Sandbox Code Playgroud)