月曜日, 1月 18, 2010

【Google App Engine】 すごいのはGDriveより全文検索でしょ!? このエントリーを含むはてなブックマーク


Google Docsのオンライン・ファイルストレージ機能

 先日、Google Docsにオンライン・ファイルストレージ機能を追加するという発表があった。画像・動画、ZIPファイルなどあらゆる種類のファイルをGoogle Docsで保管でき、アップロードしたファイルは検索機能や共有フォルダ機能の対象にもなる。アップロードできるファイルのサイズは1つにつきMAX250MB※までだが、全体の容量の制限はなく、1GBまでは無料である。それ以上は追加で購入できる。ストレージの値段は、現時点で20GBが5ドル/年だが、Google Apps Premier Editionユーザーに対しては、1GB=3.50ドル/年で今後数ヶ月以内に提供する計画とのこと。
(※ MAX1Gに変更された。2010/1/28
 Documents List API: Upload any file and more (1/12/2010)

ついにGDrive実現、「Google Docs」に オンラインストレージ機能

全文検索の話

 Documents List APIの一番大きな目玉はなんといっても全文検索APIである。Protocol Guide (v3.0)で「Performing a full text query」が New になっていないところをみると、もともとあった機能のようだが、今回から容量制限がなくなり、XMLやテキストファイルを登録できるようになったことで、やっと実用的になったのではないか。(サンプルプログラムによる検証を参照)
 本題に入る前に、これまでのGAEにおける全文検索の実装方法についてまとめてみる。

 1) DatastoreのPropertyIndexを利用する方法。これは、完全一致か前方一致しかできず、長さもStringの500バイトまでが上限。(Text型だと1MBまで格納できるがIndexを張れない)。使用するStrageの容量は格納するデータサイズの1倍以下。

 2) N-gram検索。これには2つの意味がある。(①と②のb.は区別する)

  ① 転置インデックスのキーの切り出しを、辞書や構文解析に基づくのではなく、単に一定の文字数で切り出した語を入れる方法
     a.ユニグラム = unigram (1文字単位)
     b.バイグラム = bigram (2文字単位)
     c.トリグラム = trigram (3文字単位)

  ② 分かち書きで切り出す方法
     a.形態素解析(いわゆる転置Indexの実装)
     b.N-gram(GoogleやYahooなどが採用している直前の(N-1)個の単語を見て、次の単語を予測するモデル(参考

 SuffixArrayは①のユニグラムと同等のものとなる。漏れはないが、データ量は膨大になる。nが単語のサイズとして、n+(n-1)+・・・+1 = (n+1)*n/2。また、nの最大は500バイトまで。
 ②の形態素解析でよく使われるロジックは、KAKASIや、TinySegmenterなどがある。ちなみに、TinySegmenter Java版の実装はココにある。

 GAEにおいて現実的な実装と思われるものは、①のSuffixArrayと、②のTinySegmenterだろう。①はデータ量が膨大になることと、最大サイズが500バイトまでなので、長い文章には向かない。②は長い文章でも大丈夫だが、分かち書きの精度に問題があって、使い物になるかどうかはよくわからない。
 Google Documents List Data APIの精度は、検証結果からみて②のb.ではないかと思う。とてもよい品質なので、これで十分だと思われるが、漏れが完全になくなるわけではないので、完全性が必要な項目にはSuffixArrayを使うとよいと思う。
 注意点としては、Google Apps Premier Editionユーザーでないと、Documents List APIを使えないこと。ストレージの値段がGAEよりも2倍ほど高くなり、現在はまだストレージを追加購入できない。

サンプルプログラムによる検証

  1. Google Docs Serviceの生成と認証

    DocsService service = new DocsService(appName);
    service.setUserCredentials(user, pass);


  2. Google Docsの全文検索

    URL feedUri = new URL("https://docs.google.com/feeds/default/private/full/");
    DocumentQuery query = new DocumentQuery(feedUri);
    query.setFullTextQuery(word);
    DocumentListFeed feed = service.getFeed(query, DocumentListFeed.class);


  3. ポイント
    • テキスト形式(text/plain)が対象
      • Google Documents List Data APIを使用してアップロードしたmimeType="text/plain"のXMLファイルは検索対象となった。
      • Google DocsのページからアップロードしたXMLファイルは検索対象とならなかった。
      • Google DocsのページからアップロードしたTXTファイルは検索対象となった。
      • Google DocsのページからアップロードしたExcelファイルは検索対象とならなかった。
    • インデックス生成
      • アップロード後、すぐに検索対象となった。
    • 検索ワード
      • 「半茹で冷凍又は・・・」という文字列について
        • 「半茹で」はヒットした。○
        • 「半茹」はヒットしなかった。×
        • 「冷凍」はヒットした。○
        • 「冷凍又」はヒットしなかった。×
        • 「冷凍又は」はヒットした。○
      • 「東京都調布市深大寺東町1-XX-X」という住所文字列について
        • 「調布市」はヒットした。○
        • 「深大寺」はヒットした。○
        • 「深大寺東」はヒットしなかった。×
        • 「東町」はヒットした。○
        • 「東町1」はヒットした。○


XMLファイルをGoogle Docsにアップロードする。

  1. Google Docs Serviceの生成と認証

    DocsService service = new DocsService(appName);
    service.setUserCredentials(user, pass);

    DocumentListEntry uploadedEntry = uploadFile(service, fileName, title);

  2. Google Docsへアップロード

    public DocumentListEntry uploadFile(DocsService service, String filepath, String title)
    throws IOException, ServiceException {
    File file = new File(filepath);
    //String mimeType = DocumentListEntry.MediaType.fromFileName(file.getName()).getMimeType();
    String mimeType = "text/plain";

    DocumentListEntry newDocument = new DocumentListEntry();
    newDocument.setFile(file, mimeType);
    newDocument.setTitle(new PlainTextConstruct(title));

    return service.insert(new URL("https://docs.google.com/feeds/default/private/full/"), newDocument);
    }

    • Googleのサンプルにあった
      String mimeType = DocumentListEntry.MediaType.fromFileName(file.getName()).getMimeType();
      を実行すると
      java.lang.IllegalArgumentException: No enum const class com.google.gdata.data.docs.DocumentListEntry$MediaType.XML
      とエラーが発生する。
    • mimeTypeを"text/xml"に固定で設定すると
      com.google.gdata.util.InvalidEntryException: Content-Type text/xml is not a valid media type.
      アップロード時に上記エラーとなる。
      "application/xml"でも同じくエラー。
    • "text/plain"で正常にアップロードできた。
その他
  • EUC形式のXMLファイルをアップロードしたが、その後ブラウザからダウンロードするとUTF-8形式に変換されていた。
    またXMLの括弧"<"">"が、"<<"">>"に変換されていた。
  • アップロードのURLにパラメータ"?convert=false"を付けると変換なしにアップロードされる。
    ただし、全文検索対象とならない。
    • 登録はconvert=trueで行い、取得についてXMLの括弧"<<"">>"を"<"">"に変換するのが妥当か?


0 件のコメント:

 
© 2006-2015 Virtual Technology
当サイトではGoogle Analyticsを使ってウェブサイトのトラフィック情報を収集しています。詳しくは、プライバシーポリシーを参照してください。