none
フルテキストインデックスを利用した全文検索について RRS feed

  • 質問

  •  【調査依頼事項】
     フルテキストインデックスを利用した全文検索にて、以下の文字を検索クエリに指定する方法について
     ご教示いただきたいです。
     ・「'」(シングルクォーテーション)
     ・「"」(ダブルクォーテーション)
     ・「%」(パーセント)
     ・「_」(アンダースコア)
     ・「[」(半角中カッコ)
     ・「*」(アスタリスク)
    
     現在は、全文検索の検索クエリにおいて、CONTAINS述語の引数としてクエリを渡す時に、
     クエリ全体はシングルクオートで囲み、クエリの中の単語はダブルクオートで囲んでいますが、
     以下の事象が確認されたためお問い合わせさせていただきます。
    
    
    【事象】 
     シングルクオートやダブルクオートを含む文字列をクエリに指定した場合、
     それらが語句に含まれていないものが検索される事があります。
    
     以下に列を示します。
    
     ・サンプルデータ  
     “get_element”という語句がフルテキスト索引に含まれているとします。
     確認SQL:select * from sys.dm_fts_index_keywords(DB_ID('DB'), OBJECT_ID('XXX'));
    
     以下の4パターンすべてにおいて、データが検索されます。
    
     ・パターンA
      SQL:select * from TABLE CONTAINS (tbody, '"get_element"'));    
    
     ・パターンB
      SQL:select * from TABLE CONTAINS (tbody, '"get""element"'));
    
     ・パターンC
      SQL:select * from TABLE CONTAINS (tbody, '"get__element"'));
    
     ・パターンD
      SQL:select * from TABLE CONTAINS (tbody, '"get*"'));
    
    
    【確認事項1】
    
     クエリの引数である文字列のエスケープ方法は以下で正しいでしょうか?
      ・「'」=> 「''」(2重化)
      ・「"」=> 「""」(2重化)
      ・「%」=> 必要なし
      ・「_」=> 必要なし
      ・「[」=> 必要なし
    
    
    【確認事項2】
    
     なぜ索引中に存在していないように見えるデータが検索されるのでしょうか?
    
    
    【確認事項3】
    
     「*」(アスタリスク)を1つの文字として検索する方法はないのでしょうか?
    
    
    以上となります。
    
    ご確認のほどよろしくお願い申し上げます。
    2019年7月1日 9:52

回答

  • NeoTech35さん、こんにちは。フォーラムオペレーターのHarukaです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    全文検索は、データベースを検索するより高度な方法です。
    全文検索では、行をスキャンしたり、用語がどの列に格納されているかを知る必要なく、テーブル内のすべての用語 (単語) のインスタンスをすばやく検索できます。
    全文検索は、テキストインデックスを使用して機能します。
    テキストインデックスには、テキストインデックスを作成する列にあるすべての用語の位置情報が格納されます。
    テキストインデックスを使用する方が、通常のインデックスを使用して特定の値を含む行を検索するよりも高速です。
    マッチングはパターンベースではなく用語ベースであるため、SQL Anywhere の全文検索機能は、LIKE、REGEXP、SIMILAR TO などの述語を使用した検索とは異なります。

    >【確認事項1】
    クエリの引数である文字列のエスケープ方法は以下で正しいでしょうか?
    →それが正しいと思います。 探しているものによって異なります。
    フルテキストインデックスの処理を制御する要素は、CREATE FULLTEXT INDEXコマンドで使用する設定によって異なります。
    言語 - その言語の規則に従って単語と句の解析を制御します。
    単語リストの停止 - 文字列内の位置は認識されますが、検索から除外される単語。
    アクセントの感度 - アクセントを処理するか無視するかを決定します。

    >【確認事項2】
    なぜ索引中に存在していないように見えるデータが検索されるのでしょうか?
    →前述のように、フルテキストインデックスの処理を制御する要素は、CREATE FULLTEXT INDEXコマンドで使用する設定によって異なります。 ご自身の設定を確認してください。

    >【確認事項3】
    「*」(アスタリスク)を1つの文字として検索する方法はないのでしょうか?
    →たとえば、CONTAINS(Description、 '"top *"')のようになります。 
    アスタリスク(*)の前に指定されたテキストと一致するすべてのテキストが返されます。 
    CONTAINS(DESCRIPTION、 'top *')のようにテキストとアスタリスクがダブルクォーテーションで区切られていない場合、全文検索ではアスタリスクはワイルドカードと見なされません。 
    ダブルクォーテーションを追加してみてください。

    詳細については、フルテキスト検索でのクエリを参照してください。

    上記の情報がお役に立てれば幸いです。

    どうぞよろしくお願いいたします。


    MSDN/ TechNet Community Support Haruka

    ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、
    ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    • 回答としてマーク NeoTech35 2019年7月18日 0:27
    2019年7月8日 5:35
    モデレータ

すべての返信

  • NeoTech35さん、こんにちは。フォーラムオペレーターのHarukaです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    詳細な状況をご提供いただきありがとうございます。その後のご状況いかがでしょうか。
    追加でご確認いただいたことなどあれば、追記いただくことで回答がつきやすくなります。

    どうぞよろしくお願いいたします。


    MSDN/ TechNet Community Support Haruka

    ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、
    ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    2019年7月4日 7:22
    モデレータ
  • NeoTech35さん、こんにちは。フォーラムオペレーターのHarukaです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    全文検索は、データベースを検索するより高度な方法です。
    全文検索では、行をスキャンしたり、用語がどの列に格納されているかを知る必要なく、テーブル内のすべての用語 (単語) のインスタンスをすばやく検索できます。
    全文検索は、テキストインデックスを使用して機能します。
    テキストインデックスには、テキストインデックスを作成する列にあるすべての用語の位置情報が格納されます。
    テキストインデックスを使用する方が、通常のインデックスを使用して特定の値を含む行を検索するよりも高速です。
    マッチングはパターンベースではなく用語ベースであるため、SQL Anywhere の全文検索機能は、LIKE、REGEXP、SIMILAR TO などの述語を使用した検索とは異なります。

    >【確認事項1】
    クエリの引数である文字列のエスケープ方法は以下で正しいでしょうか?
    →それが正しいと思います。 探しているものによって異なります。
    フルテキストインデックスの処理を制御する要素は、CREATE FULLTEXT INDEXコマンドで使用する設定によって異なります。
    言語 - その言語の規則に従って単語と句の解析を制御します。
    単語リストの停止 - 文字列内の位置は認識されますが、検索から除外される単語。
    アクセントの感度 - アクセントを処理するか無視するかを決定します。

    >【確認事項2】
    なぜ索引中に存在していないように見えるデータが検索されるのでしょうか?
    →前述のように、フルテキストインデックスの処理を制御する要素は、CREATE FULLTEXT INDEXコマンドで使用する設定によって異なります。 ご自身の設定を確認してください。

    >【確認事項3】
    「*」(アスタリスク)を1つの文字として検索する方法はないのでしょうか?
    →たとえば、CONTAINS(Description、 '"top *"')のようになります。 
    アスタリスク(*)の前に指定されたテキストと一致するすべてのテキストが返されます。 
    CONTAINS(DESCRIPTION、 'top *')のようにテキストとアスタリスクがダブルクォーテーションで区切られていない場合、全文検索ではアスタリスクはワイルドカードと見なされません。 
    ダブルクォーテーションを追加してみてください。

    詳細については、フルテキスト検索でのクエリを参照してください。

    上記の情報がお役に立てれば幸いです。

    どうぞよろしくお願いいたします。


    MSDN/ TechNet Community Support Haruka

    ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、
    ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    • 回答としてマーク NeoTech35 2019年7月18日 0:27
    2019年7月8日 5:35
    モデレータ
  • Haruka様

    丁寧なご回答ありがとうございました。

    追加でご質問させていただきたい事がございます。

    以下の3文を登録しています。

    1.この度は、お悔やみ申し上げます。

    2.大変申し訳ございません。これからは気を付けます。

    3.お世話になっております。よろしくお願いいたします。

    この場合に、「度」・「申し上げます」・「気」・「付けます」・「世話」・「お願いいたします」などは検索可能です。

    しかし、「これから」・「この度」・「お世話」などは検索されません。

    ワードブレイカーの仕様かとも思いますし、接頭語や接尾語については除去されて索引が作成されているのは索引の中身を確認して存じております。

    確認したいのは、索引作成時のワードブレイカーの仕様や規則が公式に提供されているかどうかについてです。

    現状、索引の中身を確認してからでないと、そのワードが検索可能な文字列であるかどうかの判断ができない状況にあります。

    LIKE検索とは用途が異なることは理解した上で利用しようと検討しており、索引化の規則が分かるようなマニュアル等があるようでしたらご教示ください。

    よろしくお願い申し上げます。

    2019年7月18日 0:53
  • Haruka様

    追加で質問させていただいているのですが、ご回答は難しいでしょうか?

    公式見解がないということでしたらその旨をご回答いただくか、有料での質問が可能ならインシデントを発行して適切な経路でご質問させていただく事も検討しますので、ご案内いただけますと幸甚です。

    改めましてご確認のほどよろしくお願いいたします。

    2019年8月5日 0:47