Edited at

Oracle Text まとめ 全文検索 CONTAINS関数の仕様

日本語文字列を扱う時

JAPANESE_VGRAM_LEXER 

Oracle 全文検索 CONTAINS関数 の仕様まとめ


ざっくりいうと

全文検索CONTAINSはあいまい検索LIKEとはちがう

検索の仕様を知らないとHITしなくて困る


よくあるはなし

・「Facebook」が「face」で検索しているのにHITしない

・「製造番号ABC-1234」が「ABC-1234」で検索してるのにHITしない

・「IT企業」が「IT」で検索を行ってもHITしない

文末で解決方法を書いています


CONTAINS関数 基本的な使い方

textというカラムの中に「オラクル」という文字列があるかどうか調べるには

where 句で下記のようにする

WHERE CONTAINS (text, 'オラクル') > 0

索引情報を参照するため

事前にtextのindexは登録してSYNCしておく必要がある

だいなりで 0以外の数値を書いてはいけない


使える演算子

「AND(&)」「OR(|)」「ACCUM(,)」「NOT(~)」「MINUS(-)」「MNOT」

基本的にはANDとORとNOTさえ覚えれば良い。演算記号には注意する


AND演算 & アンド

WHERE CONTAINS (text, 'オラクル and 日本') > 0

WHERE CONTAINS (text, 'オラクル & 日本') > 0

「オラクル」と「日本」両方が含まれているときtrueになる。順番は関係ない。


OR演算 | たてぼう

WHERE CONTAINS (text, 'オラクル or 日本') > 0

WHERE CONTAINS (text, 'オラクル | 日本') > 0

「オラクル」と「日本」どちらかが含まれているときtrueになる


NOT演算 ~ チルダ

WHERE CONTAINS (text, 'オラクル not 日本') > 0

WHERE CONTAINS (text, 'オラクル ~日本') > 0

「オラクル」があるが「日本」がないものが含まれているときtrueになる


ワイルドカード


% パーセント と _ アンダースコア

英数字のみ使える

「%」任意のn文字と一致

「_」任意の1文字と一致

WHERE CONTAINS (text, '%ac%') > 0

でtextに「Oracle」があるとtrue

日本語の検索ではワイルドカード検索は出来ない


エスケープ


 中括弧{} と \ バックスラッシュ

「{犬 AND 猫}」などのように中括弧で囲った文字全体がエスケープされる

blue\-green」などのようにして直後の演算子をエスケープできる

とりあえずなりふりかまわず中括弧で括ってしまったほうが余計なこと考えなくて良い


検索の仕様

検索文字と索引に登録されているトークンが連続で一致するとHITする


索引(index)トークンの保存され方

Oracle Text V-Gramインデックスの仕様


基本的には文字を2文字ずつトークンにわける

原文
トークン

新宿区民
[新宿][宿区][区民][民]

区切りの最後の文字は必ず1文字トークンになる


英数字の場合はシングルバイトの大文字に変換される。

原文
トークン

OracleText
[ORACLETEXT]

Oracle Text
[ORACLE][TEXT]

スペースは単語の区切りとして扱う


マルチバイト文字は漢字・カタカナ・平仮名でトークンが区切られる。

原文
トークン

日本オラクル
[日本][本][オラ][ラク][クル][ル]

日本 オラクル
[日本][本][オラ][ラク][クル][ル]

スペースは無視する


連結文字(を、ん、長音、ゃ、ゅ、ょ etc)がある時は次の文字までがトークンになる

原文
トークン

りんご
[りんご][ご]

インターフェース
[インタ][ターフ][フェース][ス]

プリン製造
[プリ][リン製][製造][造]


例外処理 内部的なあいまい検索

基本的にトークンが一致しないと検索を行ってもHITしないが例外処理がある


日本語1文字で検索をした時は例外的にトークンに%が追加されて処理される

原文
トークン

日本海
[日本][本海][海]

日本海には[本]というトークンがないが

「本」で検索を行った時[本%]として扱うためHITする


語尾が長音や「ャ」「ュ」「ョ」などで終る語句のときもトークンに%が追加される

原文
トークン

シュレディンガーの猫
[シュレ][レデ][ディンガ][ガーの][の][猫]

「ディン」というトークンはないが

「ディン」で検索を行った時[ディン%]として扱うためHITする

「シュ」でもHIT

この仕様を抑えておくと

「ィン」や「ュレ」で検索しても「シュレディンガーの猫」がHITしないのがわかる


ストップワード

英語の冠詞a、theなど、ドキュメントを特定するのに役立たないキーワードは索引情報から排除されている


英語のデフォルトストップリスト

a
all
almost
also
although

an
and
any
are
as

at
be
because
been
both

but
by
can
could
d

did
do
does
either
for

from
had
has
have
having

he
her
here
hers
him

his
how
however
i
if

in
into
is
it
its

just
ll
me
might
Mr

Mrs
Ms
my
no
non

nor
not
of
on
one

only
onto
or
our
ours

s
shall
she
should
since

so
some
still
such
t

than
that
the
their
them

then
there
therefore
these
they

this
those
though
through
thus

to
too
until
ve
very

was
we
were
what
when

where
whether
which
while
who

whose
why
will
with
would

yet
you
your
yours

これらはレクサーによってトークンに分割されたあと除去されて索引に登録される

ストップワードが存在したことだけが索引情報として記録される。

ストップワードのうち、具体的にどのストップワードが存在したのかという情報は失われる。


ストップワードによる検索

検索条件「That was the sample document.」で

文字列「This is a sample document.」を含む文書がヒットする

That was the もThis is a もストップワードであるため同一視される

検索条件「That was the very sample document.」の場合はHITしない

ストップワードの個数が異なるためHITしなくなる


注意点

日本語文書に含まれる英単語が、意図せずストップワードとして処理されてしまう場合がある。

「it」がストップワードなため

「IT」で検索を行っても「IT企業」がHITしないのはこのため

ストップリストの機能を無効にするには、CREATE INDEX時に明示的に CTXSYS.EMPTY_STOPLIST を指定するとよい


記号なども索引に登録されていない模様

公式ドキュメントに記述はみられなかったが

下記のような記号もCONTAINS関数でHITしなそうである

( ) 〔 〕 [ ] { } 〈 〉 《 》 「 」 『 』 【 】 + - ± × ÷ = ≠ < > ≦ ≧ ∞ ∴ ♂ ♀ ° ′ ″ ℃ ¥ $ ¢ £ % # & * @ § ☆ ★ ○ ● ◎ ◇ ◆ □ ■ △ ▲ ▽ ▼ ※ 〒 → ← ↑ ↓

記号も索引として意味を持たない文字となっている模様


よくあるはなし トラブルシューティング

・「Facebook」が「face」で検索しているのにHITしない

 → Facebookは[FACEBOOK]というトークンなので「Face%」と検索しないといけない

・「製造番号ABC-1234」が「ABC-1234」で検索してるのにHITしない

 →マイナス記号が演算子なので「ABC\-1234」か「{ABC-1234}」と検索するべき

・「IT企業」が「IT」で検索を行ってもHITしない

 →「it」がストップワードなのでストップリストを解除して索引をつくりなおす


参考文献

Oracle Text 詳細解説

日本オラクル株式会社

http://www.oracle.com/technetwork/jp/ondemand/db-technique/oracletext-ver12-351879-ja.pdf