Postgresql Mecabでの解析について

このQ&Aのポイント
  • Postgresのtextsearch_jaを設定しました。Mecabを使用してテーブルのデータを解析し、解析結果をtsvカラムに保存するトリガを設定しました。
  • しかし、検索時に「0000」というキーワードで検索してもレコードが取得できない問題が発生しました。to_tsqueryやplainto_tsqueryを使用した検索でも同様の結果でした。
  • 「0000」での全文検索の方法はわかりませんでしょうか?
回答を見る
  • ベストアンサー

Postgresql Mecabでの解析について

Postgresのtextsearch_jaを設定しました。 そこでMecabを使用しています。 例として以下のテーブルで create table table1 ( id int, col1 text, col2 text, tsv tsvector ); 更新処理時にtsvカラムに解析データが入るようにトリガを設定しました。 col1に「田中00001」をINSERTします。 解析するtsvカラムには「田中」と「00001」が入ります。 ここで、「0000」と検索しても、レコードを取得できませんでした。 投げたSQLは以下のような感じです。 select * from table1 where tsv @@ to_tsquery('japanese', '0000') select * from table1 where tsv @@ to_tsquery('japanese', '0000') とした場合はレコードを取得することができます。 以下も試しましたがレコードは取得できませんでした。 select * from table1 where tsv @@ plainto_tsquery('japanese', '0000') 「0000」にて検索した場合に、全文検索の機能でレコードを取得する方法はありますでしょうか? postgres8.4.5 Mecab 0.98

  • 1minn
  • お礼率84% (49/58)

質問者が選んだベストアンサー

  • ベストアンサー
  • yamada59
  • ベストアンサー率74% (29/39)
回答No.1

MeCab が 00001 を 1 つの単語として切り出してインデックスを作っているので、基本的には 0000 で検索してもヒットしません。 MeCab を使うような分かち書き方式の全文検索では、単語を切り出すときに使う辞書によるので、お望みのようなことを行うには N-gram 方式の全文検索が適しています。PostgreSQL では Senna や Groonga といった N-Gram 方式の全文検索エンジンと組み合わせた textsearch_senna や textsearch_grronga を使うのがいいでしょう。 ただ、PostgreSQL 8.4 以上をお使いのようですので、前方一致であれば MeCab でも 0000 をインデックスを使って検索できます。 SELECT * FROM table1 WHERE tsv @@ to_tsquey('japanese', '0000*');

1minn
質問者

お礼

まだ検証中ですがtextsearch_sennaを採用しようと思っています。 ありがとうございました。

関連するQ&A

  • where句のlikeと=の違いについて

    Postgresバージョン7.1.1からバージョン7.4.6にしたところ困ったことがあります。 テーブル名: hoge カラム名: col (←varchar(12)) データの中身はまるっきり同じ物が入っています。 という環境です。 そこで、SQLを実行するとバージョンによって結果が異なり不可解なのです。何か分かることがありましたら返事をお願いします。 [実行したSQL] select col from hoge where col = 'コル' select col from hoge where col like 'コル' [7.1.1] 共に、答えは一つだけ'コル'が表示されます。 [7.4.6] likeの時は'コル'が一つだけ表示されます。 =の時は何十個か出てきます。 以上、宜しくお願い致します。

  • SQL(PostgreSQL) select文

    SQLを始めたのですが、少しつまずいたので、質問させてください。 住所録検索等で、 SELECT * FROM test WHERE name LIKE '%goo%'; と書くと、nameというカラム名から goo という文字列の入ったレコードを 検索できると思います。 そこで、この goo という文字列を test テーブル全体から検索したいのですが わかりません。 teat テーブル全体から(どこのカラム名からでも)検索の仕方を教えてください。 初歩的な質問ですみません。 参考HPでもかまいません。

  • LIKEを使用したレコード抽出について

    OracleでLIKEを使用したレコード抽出で困っています。 あるテーブル(TAB_A)が以下のような属性だとします。 ------------- COL1 CHAR(5) COL2 CHAR(5) このとき、このテーブルに次のようにデータが格納されています。 COL1  COL2 -------------- ABC==  12345 [=]は便宜上1バイトスペースを表す このテーブルを対象として (1) SELECT * FROM TAB_A WHERE COL1 LIKE 'ABC%'; (2) SELECT * FROM TAB_A WHERE COL1 LIKE 'ABC==';   ([=]は便宜上1バイトスペースを表す) (3) SELECT * FROM TAB_A WHERE COL1 LIKE 'ABC'; というSQLを発行した場合に、いずれもレコードが抽出されてしまいます。(1)(2)の場合は当然だとは思うのですが、(3)でもレコードが抽出されることが理解できません。このようなことが起こり得るのでしょうか。

  • postgresqlにて全レコードのupdate

    PostgreSQLの全レコードを順次Updateしたいのですが、 SQLの記述方法がわかりません。 [やりたいこと] ユーザ情報を保持しているテーブルに、新しく"ID_TMP"カラムを追加。 カラム"ID_TMP"に、ユーザIDを保持しているカラム"ID_INFO"の内容を書き込む。 コピーしたいレコードが単一の場合、次のSQLで可能だと思うのですが、 テーブルに保持している全レコードを順次処理する方法を教えてください。 update [テーブル名] set ID_TMP = (select ID from [テーブル名] where id = [ID名]); 宜しくお願いいたします。

  • DELETE文とロックについて

    DELETEしようとしているレコードがロックされている場合は、削除せず すぐに処理を戻したいです。イメージ的にNOWAITが最適と思い →DELETE FROM テーブルA WHERE カラムA = 'A' NOWAIT としたいところですが、NOWAITはSELECT文でしか指定できないとのことなのでNGです。 SELECT文で抽出した条件のレコードを削除する場合 →DELETE FROM テーブルA WHERE カラムA =      (SELECT カラムA FROM テーブルA WHERE カラムA = 'A') と出来ます。 又、SELECT文でロック待機時間なしの場合 →SELECT カラムA FROM テーブルA WHERE カラムA = 'A' FOR UPDATE NOWAIT と出来ます。 これらを組み合わせて、ロックされているレコードを削除しようとした場合、 すぐにNGで制御を戻すように、次のように記載してみました。 →DELETE FROM テーブルA WHERE カラムA =    (SELECT カラムA FROM テーブルA WHERE カラムA = 'A' FOR UPDATE NOWAIT) なぜかNGになってしまいます(右カッコがありませんと言われます)。 なぜこの書き方が出来ないのでしょうか? 現在、一度該当のレコードをSELECT文でFOR UPDATE NOWAITをしてから DELETEをしています。 1つレコードを削除したいだけなのに、わざわざSELECT文と DELETE文を発行してしまっています。 こういう場合、他にどのような方法があるのでしょうか? 宜しくお願いします。

  • 2つのテーブルからレコードを抽出する方法

    お世話になります。MySQLに関する質問です。 TABLE1とTABLE2の2つのテーブルからレコードを抽出する際、 TABLE1からは全項目のデータを取得し、TABLE2からは一部の項目の データを取得したいと考えています。 条件は、TABLE1とTABLE2を[No]という項目の値で紐(ひも)づけます。 (1) SELECT * FROM TABLE1 (2) SELECT COL_A, COL_B, COL_C FROM TABLE2 上記(1)(2)のレコードを1つのSQLで取得する方法について、どなたかご教授願えますか?

    • ベストアンサー
    • MySQL
  • <SQL>条件付きで最小値レコードを抽出する方法

    SQLite3.7.5を使っています。 以下<抽出前>の様なテーブルから、col2の値が"FALSE"で(col1=3,4,5の3つ)かつ、col3が最小値(col3=3)であるレコードを<抽出後>のように抽出するSQL文をご教示ください。 <抽出前> col1 | col2 | col3 1 | true | 3 2 | true | 0 3 |false | 3 4 |false | 5 5 |false | 3 <抽出後> col1 | col2 | col3 3 |false | 3 5 |false | 3 自分で考えたSQL文は以下です。 抽出結果は問題ないのですが、同じSELECT文を2回書いていてだいぶ効率悪いことをしているのではないかと思い質問しました。 よろしくお願い致します。 SELECT * FROM (SELECT * FROM test WHERE (col2 = false)) WHERE col3 = (SELECT min(col3) FROM (SELECT * FROM test WHERE (col2 = false)))

  • Oracle SQLで文字列操作

    始めまして。 VB6でプログラミングをしています。DBはOracle8.16です。 Oracleテーブル上で、カテゴリー別に " 文字列 & ナンバリング " の値をもつレコードを、インサートしていく作業をしています。 ナンバリングの部分の現在の最大値に1足したものを、 新規レコードで値を持たせインサートしてます。 tblA Col1           Col2 1            NA-P1-1 1            NA-P1-2 1            NA-P1-3 1            NA-P1-4 3            NA-P3-1 3            NA-P3-2 3            NA-P3-3 1   この場合、 Select max(Col2) from tblA where Col1 = 1 で現在のCol1=1のMax値(Col2)は NA-P1-4 と取り出せるできるんですが、新規に追加するレコードのCol2の値が NA-P1-5だと取得できる方法はあるでしょうか。 Select Max(col2)+1 ~だと、カラム定義がvarchar2なんで、 当然のようにシステムに怒られました(当然ですが。。) お分かりの方、お願い致します。

  • こういう場合のSQLの書き方。

    はまっています。お知恵を貸してください。 Oracle8i WindowsNT4.0です。 tbl_testというテーブルがあります。 データが以下のように入っています。 col1   col2   col3 --------------------------------- A     B     C      A B     A     A C この時、col1 col2 col3それぞれのカラムの中で、 Aという値が何個あるか数えたいのです。 今は以下のように三つにわけてセレクトしていますが、 これをひとつの式にまとめたいのですが、可能でしょうか? UNIONしても欲しい答えは返ってきません。 =========================== SELECT COUNT(col1) AS col1 FROM tbl_test WHERE col1 = 'A' =========================== SELECT COUNT(col2) AS col2 FROM tbl_test WHERE col2 = 'A' =========================== SELECT COUNT(col3) AS col3 FROM tbl_test WHERE col3 = 'A' 欲しい答えは、 col1   col2   col3 ----------------------- 1     2     1 です。 なお、家に検証環境が無いので、検証&お礼は明日のお昼くらいになると思います。 宜しくお願い致します。

  • betweenで境界値が取得できない。

    連番の歯抜け値を取得するSQLを作りたいと思っています。 例えば、カラムAに、1,2,3,5,6,7,9,10(4と8が抜けている) と数値の入っているテーブルAがあるとします。 これに対して、 SELECT MIN(カラムA + 1) FROM テーブルA WHERE (カラムA + 1) NOT IN (SELECT カラムA FROM テーブルA) とSQLを投げた場合、4が取得できます。 これにbetween句を付与したいのですが、そうすると境界値が なぜか取れなくて困ってます。 具体的には、 SELECT MIN(カラムA + 1) FROM テーブルA WHERE (カラムA + 1) NOT IN (SELECT カラムA FROM テーブルA) AND BETWEEN 8 AND 10 とした場合、NULLが返ってきてしまいます。 普通、BETWEENは境界値も対象になるはずですが、何故このような 結果になってしまうのでしょうか? 修正点をご教授いただけないでしょうか? 宜しくお願いします。