読者です 読者をやめる 読者になる 読者になる

@thorikiriのてょりっき

@thorikiriがWebとかAndroidとかの技術ネタや本を読んだブログです

Google App EngineのFullTextSearchでHTMLファイルを検索してみる

appengine

環境はこんな次の通り

  • appengine 1.7.0
  • slim3 1.0.16

ファイルのアップロード

とりあえずは、ファイルを選択してアップロードすることろから始めたいとおもいます。
SearchServiceを利用します。SearchServiceからIndexを取得し、このIndexに対してデータを追加します。
追加するデータはDocumentで、Document.BuilderとField.Builderで作っていくのが良いですね。フィールドは、文字列や数値だけでなく、HTMLに対応しているので簡単にHMTLファイルに書かれている本文で検索することができますね。

  • HtmlModel
@Model(schemaVersion = 1)
public class HrmlModel implements Serializable {
    @Attribute(primaryKey = true)
    private Key key;
    
    private String fileName;
    
    @Attribute(lob = true)
    private String content;

    @Attribute(version = true)
    private Long version;
    // 略
}
  • HtmlModelDao
public class HtmlModelDao extends DaoBase<HtmlModel> {
    // SearchServiceを作成して、インデックスを作成する
    private static final Index INDEX = 
            SearchServiceFactory.getSearchService().getIndex(IndexSpec.newBuilder().setName("html_database"));

    @Override
    public Key put(HtmlModel model) {
        // Document.Builderでインデックスするコンテンツを作るためのBuilderを作成する
        Document.Builder builder = Document.newBuilder()
                .addField(Field.newBuilder().setName("content").setHTML(model.getContent()))
                .addField(Field.newBuilder().setName("fileName").setText(model.getFileName()));
        // Documentを作成する
        Document doc = builder.build();
        // インデックスに突っ込む
        INDEX.add(doc);
        return super.put(model);
    }
}
  • UploadController

あんまり本質的ではないので略

検索

検索も単純なものでは難しくありません。
インデックスに対して、searchメソッドで検索します。今回はString型ですが、Queryオブジェクトを使えばもっと色々出来るはずです。

  • HtmlModelDao
public class HtmlModelDao extends DaoBase<HtmlModel> {
    // SearchServiceを作成して、インデックスを作成する
    private static final Index INDEX = 
            SearchServiceFactory.getSearchService().getIndex(IndexSpec.newBuilder().setName("html_database"));

    public List<HtmlModel> findByKeyword(String keyword) {
        // キーワードでインデックスからドキュメントを検索する
        Results<ScoredDocument> documents = INDEX.search(keyword);
        List<HtmlModel> models = new ArrayList<HtmlModel>();
        for (ScoredDocument document : documents) {
            // 検索したドキュメントをModelクラスに変換する
            // 今回KeyとかVersionは含めてないです
            HtmlModel model = new HtmlModel();
            model.setFileName(document.getOnlyField("fileName").getText());
            model.setContent(document.getOnlyField("content").getHTML());
            models.add(model);
        }
        return models;
    }
}

まぁ、まだ日本語に対応していないんですけどね。

Google API Expertが解説する Google App Engine for Java実践ガイド

Google API Expertが解説する Google App Engine for Java実践ガイド

この本にはYahoo!の形態要素解析APIを使って日本語の全文検索を試みる話も乗ってました。