1

說我有以下僞模式,其中1-many關係使用的Postgres陣列建模:Postgres的用複合類型的陣列FTS

CREATE TYPE quotes AS 
(
    text CHARACTER VARYING, 
    is_direct CHARACTER VARYING 
); 

CREATE TABLE posts 
(
    body CHARACTER VARYING, 
    q  quotes[] 
); 
insert into posts(body,q) VALUES('ninjas rock',ARRAY[ ROW('I AGREE',True)::quotes, ROW('I DISAGREE',FALSE)::quotes ]); 

我的第一個問題是:?要如何進行一個選擇,以從整個陣列中過濾掉quote->text

這工作:

test=# select body, q[1].text from posts; 
    body  | text 
--------------+--------- 
hassan rocks | I AGREE 
(1 row) 

但這並不(注意,整個複合型已被檢索):

test=# select body, (q).text from posts; 
    body  |      text      
--------------+------------------------------------------------- 
hassan rocks | {"(\"I AGREE\",true)","(\"I DISAGREE\",false)"} 
(1 row) 

爲了彌補到我真正的問題,我會怎樣創建一個杜松子酒或要點(有或沒有to_tsvector)索引,其中包括帖子正文的文本以及所有的報價文本?我不想使用索引的額外列方法作爲觸發器make me sad

目前我的模式代表帖子和報價爲1-many關係,但是我認爲如果postgres支持我正在嘗試做的事情,它會大大簡化事情。

回答

1

您可以創建一個函數來獲取數組的部分和回報爲SETOF quotes,並呼籲SELECT的funcion:

CREATE OR REPLACE FUNCTION getquote(posts) 
RETURNS SETOF quotes 
LANGUAGE sql 
AS $getquote$ 
SELECT $1.q[i].text, $1.q[i].is_direct 
FROM generate_series(array_lower($1.q, 1), array_upper($1.q, 1)) AS i 
$getquote$ 

而且SELECT是:

SELECT body, (getquote(p)).* FROM posts p; 

您可以創建使事情變得更簡單的視圖,並且您還可以對函數本身執行篩選任務。

0

以下代碼將「過濾」您的數組。 select (unnest(q)).text from posts;unnest將數組轉換爲行。請注意0​​包裹在括號中,這很重要,因爲如果沒有括號,您將無法選擇特定字段 - 即unnest(q).text無效,並且unnest(q)本身會生成包含字符串形式的組合的行。

治療後TXT和報價TXT的文本的一個單元的代碼如下:

SELECT to_tsvector(q.b_txt || q.q_t) FROM 
(
    SELECT b_txt,string_agg(p.q_txt,' ') as q_t 
    FROM (SELECT 1 AS id,body b_txt, (unnest(q)).text AS q_txt FROM posts) AS p 
    GROUP BY p.id,b_txt 
) AS q; 

這可能需要被改編成UDF用於gingist索引。

0

我可以回答第1部分。

要返回一行身體的每個/報價:

SELECT posts.body, array_agg(q_unnest.text) AS quotes 
FROM posts, UNNEST(q) AS q_unnest 
GROUP BY posts.body 

要返回一行對每個崗位有:

SELECT body, q_unnest.text AS quote 
FROM posts, UNNEST(q) AS q_unnest 

要與報價文本的數組,每個帖子返回一行

SELECT posts.body, array_to_string(array_agg(q_unnest.text), '|') AS quotes 
FROM posts, UNNEST(q) AS q_unnest 
GROUP BY posts.body 

我建立一個SQLFiddle所以你可以嘗試它爲你:報價文本由分隔符小精靈。

至於第2部分和索引複合類型的數組,我認爲它需要一個「操作員類」,根據Postgres擴展指南here。這對我來說看起來很麻煩,我還沒有找到如何去做的例子。