データストアに格納するエンティティに持たせるプロパティ、このプロパティが利用できる型の中で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型を意識しないでいいように、した。