3

(これはすべて、Ubuntu 10.04、FWIW 上の PostgreSQL 9.0.1 で行われました。)

私は、二重メタフォン アルゴリズムに基づいて、PostgreSQL 用に名前専用の独自の字句変換関数を作成しようとしました。C lexize 関数を生成するために、dict_xsyn の例から始めて、基本的に同義語ルックアップのために double metaphone を交換しました。

しかし、おそらく 20% のto_tsvector確率で呼び出され、語彙素を落としているようです。例として、米国国勢調査局の名前のリストを含むテーブルを作成しました。

db=# select * from names order by rank limit 8;
   name   | freq  | cumfreq | rank 
----------+-------+---------+------
 SMITH    | 1.006 |   1.006 |    1
 JOHNSON  |  0.81 |   1.816 |    2
 WILLIAMS | 0.699 |   2.515 |    3
 JONES    | 0.621 |   3.136 |    4
 BROWN    | 0.621 |   3.757 |    5
 DAVIS    |  0.48 |   4.237 |    6
 MILLER   | 0.424 |    4.66 |    7
 WILSON   | 0.339 |       5 |    8
(8 rows)

次に、ベクター列を追加してto_tsvector、メタフォン ディクショナリを入力します。

db=# alter table names add column vec tsvector;
ALTER TABLE
db=# update names set vec=to_tsvector('public.names', name);
UPDATE 88799
db=# select * from names order by rank limit 8;
   name   | freq  | cumfreq | rank |              vec              
----------+-------+---------+------+-------------------------------
 SMITH    | 1.006 |   1.006 |    1 | 
 JOHNSON  |  0.81 |   1.816 |    2 | 'ANSN':1 'JNSN':1 'johnson':1
 WILLIAMS | 0.699 |   2.515 |    3 | 
 JONES    | 0.621 |   3.136 |    4 | 
 BROWN    | 0.621 |   3.757 |    5 | 
 DAVIS    |  0.48 |   4.237 |    6 | 
 MILLER   | 0.424 |    4.66 |    7 | 'MLR':1 'miller':1
 WILSON   | 0.339 |       5 |    8 | 'ALSN':1 'FLSN':1 'wilson':1
(8 rows)

多数の vec フィールドが空です! 実際には:

db=# select count(1) from names where vec = to_tsvector('');
 count 
-------
 41101
(1 row)

その一括更新を実行してから、一致しないフィールドを繰り返しカウントし、毎回異なるカウントを取得できます。これは、異なる行で実際のベクトルが計算されていないためです。

しかし、私のレキシズ関数自体は大丈夫だと思いますか?

db=# alter table names drop column vec; alter table names add column lexemes varchar[];
ALTER TABLE
ALTER TABLE
db=# update names set lexemes=ts_lexize('dmetaphonedict', name);
UPDATE 88799
db=# select * from names order by rank limit 10;
   name   | freq  | cumfreq | rank |       lexemes        
----------+-------+---------+------+----------------------
 SMITH    | 1.006 |   1.006 |    1 | {smith,SM0,XMT}
 JOHNSON  |  0.81 |   1.816 |    2 | {johnson,JNSN,ANSN}
 WILLIAMS | 0.699 |   2.515 |    3 | {williams,ALMS,FLMS}
 JONES    | 0.621 |   3.136 |    4 | {jones,JNS,ANS}
 BROWN    | 0.621 |   3.757 |    5 | {brown,PRN}
 DAVIS    |  0.48 |   4.237 |    6 | {davis,TFS}
 MILLER   | 0.424 |    4.66 |    7 | {miller,MLR}
 WILSON   | 0.339 |       5 |    8 | {wilson,ALSN,FLSN}
 MOORE    | 0.312 |   5.312 |    9 | {moore,MR}
 TAYLOR   | 0.311 |   5.623 |   10 | {taylor,TLR}
(10 rows)
db=# select count(1) from names where array_length(lexemes,1)=0;
 count 
-------
     0
(1 row)

私はそれを何度も行うことができ、毎回0の不一致を得ることができます.

関連するテキスト検索辞書と構成を次のように作成しています。

CREATE OR REPLACE FUNCTION ddmetaphonedict_init(internal)
        RETURNS internal
        AS '$libdir/dict_dmetaphone'
        LANGUAGE C STRICT;

CREATE OR REPLACE FUNCTION ddmetaphonedict_lexize(internal, internal, internal, internal)
        RETURNS internal
        AS '$libdir/dict_dmetaphone'
        LANGUAGE C STRICT;

CREATE TEXT SEARCH TEMPLATE dmetaphonedict_template (
        LEXIZE = ddmetaphonedict_lexize,
        INIT   = ddmetaphonedict_init
);

CREATE TEXT SEARCH DICTIONARY dmetaphonedict (
        TEMPLATE = dmetaphonedict_template
);

COMMENT ON TEXT SEARCH DICTIONARY dmetaphonedict IS 'dictionary for names, using dmetaphone';

create text search configuration names (copy=english);
alter text search configuration names alter mapping for asciiword, asciihword, word, hword with dmetaphonedict;

dict_xsyn の例からほぼそのままです。

どうしたの?これらのものがどこにドロップされているかを把握するにはどうすればよいですか?

追加: 9.1 でこれを試してみました。to_tsvector が不発の tsvector を生成する速度は大幅に減少します (80000 以上のレコードのうち 5 (5k ではなく 5 だけ) から 7000 レコード)。しかし、彼らはまだそこにいます。

4

1 に答える 1

1

まず、原因としてto_tsvector()を削除したいと思います。

最初にto_tsvector()を変更して、定数を返すようにします。たとえば、入力引数が何であっても、「'ANSN':1'JNSN':1'johnson':1」を返すように変更します。(入力引数がNULLの場合でも。)一括更新で「vec」列に穴が残っている場合は、to_tsvector()がクリアされると思います。

私はそれについて正しいですか?

また、lexize()を使用して「語彙素」列にデータを入力し、次に別の関数を使用して語彙素を読み取り、「vec」列に値を生成する2段階のプロセスを検討してください。

于 2011-01-17T23:07:48.013 に答える