[pgsql-jp: 39511] Re: PostgresのXML予想

ITAGAKI Takahiro itagaki.takahiro @ oss.ntt.co.jp
2008年 7月 23日 (水) 12:14:43 JST


koyama <mlus @ hintmark.com> wrote:

> Postgres8.3で、XMLのサポート(SQL2003でしたっけ)に対応しましたが、
> 私が理解している限り、特定カラムに入力されたxmlの要素をwhereに指定して
> 検索できないように思えます。

どういう根拠で「できない」と判断されたか分かりませんが、xpath を条件として
絞り込むこともできますよ。ただ、xpath 関数は xml[] 型を返すことに注意が
必要かもしれません。xml 型には比較演算子が用意されていないため、text などの
他の型に変換して扱うケースが多いと思われます。

----
=# CREATE TABLE book (id integer PRIMARY KEY, contents xml);
=# INSERT INTO book VALUES(1, '<book>
  <title>Book1</title>
  <author>Author1</author>
</book>');
=# INSERT INTO book VALUES(2, '<book>
  <title>Book2</title>
  <author>Author1</author>
  <author>Author2</author>
</book>');

=# SELECT id FROM book
   WHERE (xpath('/book/title/text()', contents))[1]::text = 'Book1';
=# SELECT id FROM book
   WHERE xpath('/book/author/text()', contents)::text[] @> ARRAY['Author1'];
----

インデックスが必要ならば、xpath での抽出結果を text や text[] として扱い、
btree や gin で関数インデックスを張ることができます。
ただ、記述が煩雑ですし、検索の柔軟性に欠けることは否めません。

----
=# CREATE INDEX idx_title ON book
   USING btree(((xpath('/book/title/text()', contents))[1]::text));
=# CREATE INDEX idx_authors ON book
   USING gin((xpath('/book/author/text()', contents)::text[]));

=# EXPLAIN SELECT id FROM book
   WHERE (xpath('/book/title/text()', contents))[1]::text = 'Book1';
                                               QUERY PLAN
--------------------------------------------------------------------------------------------------------
 Index Scan using idx_title on book  (cost=0.00..8.27 rows=1 width=4)
   Index Cond: (((xpath('/book/title/text()'::text, contents, '{}'::text[]))[1])::text = 'Book1'::text)
(2 rows)

=# EXPLAIN SELECT id FROM book
   WHERE xpath('/book/author/text()', contents)::text[] @> ARRAY['Author1'];
                                                 QUERY PLAN
-------------------------------------------------------------------------------------------------------------
 Index Scan using idx_authors on book  (cost=0.00..8.27 rows=1 width=4)
   Index Cond: ((xpath('/book/author/text()'::text, contents, '{}'::text[]))::text[] @> '{Author1}'::text[])
(2 rows)
----


------------------------------------------------------------
板垣貴裕 <itagaki.takahiro @ oss.ntt.co.jp>





pgsql-jp メーリングリストの案内