Postgresql 在短语中添加多个短语以进行查询

Postgresql 在短语中添加多个短语以进行查询,postgresql,full-text-search,postgresql-9.6,tsvector,Postgresql,Full Text Search,Postgresql 9.6,Tsvector,我已经成功地将单个单词的数组转换成字符串,但是Postgres9.6中的短语只允许一个关键字短语。是否有人知道一种查询tsvector(无论是Sql还是全文搜索功能)的解决方案,我可以(或/和)在查询中输入动态数量的短语。选择块都是文本数组 第一次尝试: SELECT to_tsvector('english','Try not to become a man of successful companies, but rather try to become a man of value')

我已经成功地将单个单词的数组转换成字符串,但是Postgres9.6中的短语只允许一个关键字短语。是否有人知道一种查询tsvector(无论是Sql还是全文搜索功能)的解决方案,我可以(或/和)在查询中输入动态数量的短语。选择块都是文本数组

第一次尝试:

SELECT to_tsvector('english','Try not to become a man of successful companies, but rather try to become a man of value')
   @@ (to_tsquery('english','man & become')
       && phraseto_tsquery('english','man of value')
       && phraseto_tsquery('english','company')
       || phraseto_tsquery('english', 'company | man of value')
   );
搜索动物的现实问题示例:

-- with statements here of opp_tsv and tp
SELECT
  tp.id,
  tp.keywords, --['giraffes','lions', 'monkeys']
  tp.phrase_keywords, --['pygmy marmocet','African Lion']
  tp.neg_keywords, --['aliens', 'spaceships', 'space']
  tp.neg_phrase_keywords --['Andromedan Alien', 'Nibiru Reptilian']
FROM tp, opp_tsv,
  -- string logic for ts_query
      concat(array_to_string(tp.keywords, ' | ')) AS kws_concat,
      concat(array_to_string(tp.neg_keywords, ' | ')) AS     neg_kws_concat,
      to_tsquery('english', kws_concat) query,
      to_tsquery('english', concat(neg_kws_concat)) neg_query
  -- Case logic for phrase queries

  -- .... -> phrase_query,
      phraseto_tsquery('phrase to search | Need this phrase too')
  -- .... -> phrase_neg_query,

WHERE
  (
    opp_tsv.doc @@ query --pos
    OR
    opp_tsv.doc @@ phrase_query --pos
  )
  AND NOT (
    opp_tsv.doc @@ neg_query --neg
    OR
    opp_tsv.doc @@ phrase_neg_query --neg
  )
ORDER BY rank_cd DESC;
想法: 根据数组长度动态生成

opp_tsv.doc@(短语查询短语查询2)

或者以某种方式实现这一点

opp\u tsv.doc@@phraseto\u tsquery('big messy phrase | more messy wordphrases')

编辑:
选择短语to_tsquery(“要搜索的短语|也需要这个短语”)
结果=
“短语”到“搜索”也需要“这个短语”
我要查找的是
'phrasetosearch'|“needthishphrasetoo”
通过
tsquery
或(
|
)运算符的结果:

CREATE AGGREGATE tsquery_or_agg(tsquery) (
  SFUNC = tsquery_or,
  STYPE = tsquery
);
注意:上述聚合取决于
tsquery
|
运算符由
tsquery\u或(tsquery,tsquery)
函数支持。您可以通过以下方式进行检查:

SELECT *
FROM   pg_operator
WHERE  oprname  = '||'
AND    oprleft  = regtype 'tsquery'
AND    oprright = regtype 'tsquery';
如果不想依赖此(未记录)函数的名称(即使不太可能更改),可以创建自己的函数作为聚合的基函数(
SFUNC
):

CREATE FUNCTION my_tsquery_or(tsquery, tsquery)
  RETURNS tsquery
  LANGUAGE sql
  IMMUTABLE
  STRICT
  AS 'SELECT $1 || $2';
之后,您的查询将类似于:

WITH tp(id, keywords, phrase_keywords, neg_keywords, neg_phrase_keywords ) AS (
  VALUES (42, ARRAY['giraffes', 'lions', 'monkeys']::text[],
              ARRAY['pygmy marmocet', 'African Lion']::text[],
              ARRAY['aliens', 'spaceships', 'space']::text[],
              ARRAY['Andromedan Alien', 'Nibiru Reptilian']::text[])
),
tq(id, query) AS (
  SELECT   tp.id,
           (((SELECT tsquery_or_agg(plainto_tsquery(kw)) FROM unnest(keywords) kw) ||
             (SELECT tsquery_or_agg(phraseto_tsquery(pk)) FROM unnest(phrase_keywords) pk)) &&
             !!((SELECT tsquery_or_agg(plainto_tsquery(nk)) FROM unnest(neg_keywords) nk) ||
                (SELECT tsquery_or_agg(phraseto_tsquery(np)) FROM unnest(neg_phrase_keywords) np)))
  FROM     tp
),
opp_tsv(doc) AS (
  VALUES (to_tsvector('Earth''s African Lions')),
         (to_tsvector('Andromedan Alien''s space monkeys'))
)
SELECT   tp.id,
         tp.keywords,
         tp.phrase_keywords,
         tp.neg_keywords,
         tp.neg_phrase_keywords,
         opp_tsv.doc
FROM     opp_tsv, tp
JOIN     tq USING (id)
WHERE    opp_tsv.doc @@ tq.query
ORDER BY ts_rank_cd(opp_tsv.doc, tq.query) DESC;
tq(id, query) AS (
  SELECT   tp.id,
           (((SELECT tsquery_or_agg(plainto_tsquery(kw)) FROM unnest(keywords) kwb, regexp_split_to_table(kwb, '\|') kw) ||
             (SELECT tsquery_or_agg(phraseto_tsquery(pk)) FROM unnest(phrase_keywords) pkb, regexp_split_to_table(pkb, '\|') pk)) &&
             !!((SELECT tsquery_or_agg(plainto_tsquery(nk)) FROM unnest(neg_keywords) nkb, regexp_split_to_table(nkb, '\|') nk) ||
                (SELECT tsquery_or_agg(phraseto_tsquery(np)) FROM unnest(neg_phrase_keywords) npb, regexp_split_to_table(npb, '\|') np)))
  FROM     tp
),
另外,如果
tp
中的字段可以包含类似
'big-messy-phrase | more-messy-wordphrases'
这样的短语,那么您首先没有正确分割输入。您可以使用
regexp\u split\u to\u table()
函数拆分这些短语/关键字。因此,
tq
CTE应该类似于:

WITH tp(id, keywords, phrase_keywords, neg_keywords, neg_phrase_keywords ) AS (
  VALUES (42, ARRAY['giraffes', 'lions', 'monkeys']::text[],
              ARRAY['pygmy marmocet', 'African Lion']::text[],
              ARRAY['aliens', 'spaceships', 'space']::text[],
              ARRAY['Andromedan Alien', 'Nibiru Reptilian']::text[])
),
tq(id, query) AS (
  SELECT   tp.id,
           (((SELECT tsquery_or_agg(plainto_tsquery(kw)) FROM unnest(keywords) kw) ||
             (SELECT tsquery_or_agg(phraseto_tsquery(pk)) FROM unnest(phrase_keywords) pk)) &&
             !!((SELECT tsquery_or_agg(plainto_tsquery(nk)) FROM unnest(neg_keywords) nk) ||
                (SELECT tsquery_or_agg(phraseto_tsquery(np)) FROM unnest(neg_phrase_keywords) np)))
  FROM     tp
),
opp_tsv(doc) AS (
  VALUES (to_tsvector('Earth''s African Lions')),
         (to_tsvector('Andromedan Alien''s space monkeys'))
)
SELECT   tp.id,
         tp.keywords,
         tp.phrase_keywords,
         tp.neg_keywords,
         tp.neg_phrase_keywords,
         opp_tsv.doc
FROM     opp_tsv, tp
JOIN     tq USING (id)
WHERE    opp_tsv.doc @@ tq.query
ORDER BY ts_rank_cd(opp_tsv.doc, tq.query) DESC;
tq(id, query) AS (
  SELECT   tp.id,
           (((SELECT tsquery_or_agg(plainto_tsquery(kw)) FROM unnest(keywords) kwb, regexp_split_to_table(kwb, '\|') kw) ||
             (SELECT tsquery_or_agg(phraseto_tsquery(pk)) FROM unnest(phrase_keywords) pkb, regexp_split_to_table(pkb, '\|') pk)) &&
             !!((SELECT tsquery_or_agg(plainto_tsquery(nk)) FROM unnest(neg_keywords) nkb, regexp_split_to_table(nkb, '\|') nk) ||
                (SELECT tsquery_or_agg(phraseto_tsquery(np)) FROM unnest(neg_phrase_keywords) npb, regexp_split_to_table(npb, '\|') np)))
  FROM     tp
),

您可以a)围绕
tsquery
运算符
&&
|
的函数,或者b)只需使用这些
短语到tsquery
调用的输出的字符串表示,使用正确的括号,例如
concat(“(”,数组到字符串(tp.phrase|关键字)”)|(“),”)
。。。。。。但是我不确定您是否理解了
phrasetotsquery
函数的每个方面:就像
plaintotsquery
phrasetotsquery
函数将无法识别其输入中的
tsquery
运算符、权重标签或前缀匹配标签,因此
phrasetotsquery('phraseto search |也需要这个短语')
相当于
phraseto_tsquery(“搜索短语也需要这个短语”)
旁注:你可以在
WHERE
子句中有一个:
opp_tsv.doc@((query | phrase|u query)&&(neg|query | phrase| neg|query)
--如果你将这个
tsquery的结构提取到CTE中,您更可能使用索引进行搜索。我已经尝试过这个=>
phraseto\u tsquery('phraseto search |也需要这个短语')
,但它将整个输入视为一个短语。短语to_查询只能使用1个短语。谢谢你的旁注!这可以大大清理我的查询。但我仍然需要一种编程方式,根据短语的数量,在查询中添加多个短语@波茨