Hatena::Groupgae

a-knowの日記

 | 

2009-10-29

巨大なデータをデータストアに格納する

| 23:13

データストアに格納するエンティティに持たせるプロパティ、このプロパティが利用できる型の中でBlob型(com.google.appengine.api.datastore.Blob)というものがある。

これは、長い(大きな)バイナリデータを格納するためのもので、インデックスが作成されない、という特徴がある。

インデックスは、別途手動で定義もできるが、作成したアプリケーションの中で使われているクエリをもとに自動的に作成も、される。このことを考えると、フィルタや並び替え順序に使用することがないような項目は、積極的にBlob型にしておいた方が良いように思う。(ムダなインデックス生成を防ぐ)

例えばa-knowの作成しているアプリでは、3種の巨大な(数百KB~)hashmapを格納する必要があるので、この3つのプロパティBlob型にしている。


    @Persistent
    private Blob sortedListBySongPlayCount;

    @Persistent
    private Blob sortedMapByAlbumPlayCount;

    @Persistent
    private Blob sortedMapByArtistPlayCount;

    @SuppressWarnings("unchecked")
	public CDiTInfo(String loginIdyyMMddHHmmss, String loginId, String yyMMddHHmmss, String infoName, Integer totalPlayCount, ArrayList sortedListBySongPlayCount, LinkedHashMap sortedMapByAlbumPlayCount, LinkedHashMap sortedMapByArtistPlayCount) {
        this.loginIdyyMMddHHmmss = loginIdyyMMddHHmmss;
    	this.loginId = loginId;
        this.yyMMddHHmmss = yyMMddHHmmss;
        this.totalPlayCount = totalPlayCount;
        this.infoName = infoName;


        ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
        ObjectOutputStream oos1 = null;

        ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
        ObjectOutputStream oos2 = null;

        ByteArrayOutputStream baos3 = new ByteArrayOutputStream();
        ObjectOutputStream oos3 = null;

        try{
        	oos1 = new ObjectOutputStream(baos1);
        	oos1.reset();
        	oos1.writeObject(sortedListBySongPlayCount);
        	oos1.flush();


        	oos2 = new ObjectOutputStream(baos2);
        	oos2.reset();
        	oos2.writeObject(sortedMapByAlbumPlayCount);
        	oos2.flush();


        	oos3 = new ObjectOutputStream(baos3);
        	oos3.reset();
        	oos3.writeObject(sortedMapByArtistPlayCount);
        	oos3.flush();
        }catch(Exception e){
        	e.printStackTrace();
        }

        this.sortedListBySongPlayCount = new Blob(baos1.toByteArray());
        this.sortedMapByAlbumPlayCount = new Blob(baos2.toByteArray());
        this.sortedMapByArtistPlayCount = new Blob(baos3.toByteArray());
    }

もともとhashmapをそのまま格納しようとしていたこともあり、格納時にBlob型を意識しないでいいように、した。

 |