1

1-manyPostgres arrays を使用して関係がモデル化されている次の疑似スキーマがあるとします。

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、投稿本文とすべての引用テキストの両方のテキストを含むジンまたは要点 ( の有無にかかわらず) インデックスを作成するにはどうすればよいですか? トリガーが私を悲しませるので、索引付けの余分な列アプローチを使用しないことを好みます。

現在、私のスキーマは投稿と引用を1-many関係として表していますが、postgres が私がやろうとしていることをサポートしていれば、物事は大幅に簡素化されると思います。

4

3 に答える 3

1

配列部分を取得して として返す関数を作成し、 で関数を呼び出すことができSETOF quotesますSELECT

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;

ビューを作成して物事を簡単にすることもできますし、関数自体でフィルター タスクを実行することもできます。

于 2012-08-13T17:41:54.997 に答える
0

次のコードは、配列を「フィルタリング」します。select (unnest(q)).text from posts;. unnest配列を行にピボットします。は括弧で囲まれていることに注意してunnestください。括弧がないと特定のフィールドを選択できないため、これは重要です。つまり、unnest(q).text無効であり、unnest(q)それ自体が文字列形式のコンポジットを含む行になります。

投稿 txt と引用 txt を 1 つのテキスト単位として扱うコードは次のとおりです。

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;

ginこれはおそらく、またはgistインデックスで使用するために UDF に適合させる必要があります。

于 2012-08-14T05:08:15.427 に答える
0

パート 1 にお答えできます。

各本文/引用の行を返すには:

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

引用テキストの配列を含む各投稿の行を返すには:

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

区切り文字で区切られた引用テキストを含む各投稿の行を返すには:

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 拡張ガイドのこちらのように、「演算子クラス」が必要だと思います。それは私には面倒に思えますが、それを行う方法の例は見つかりませんでした。

于 2014-01-30T12:40:24.183 に答える