1

現在、アクティビティ/場所とAsyncDataProviderを使用するアプリケーションがあります。

現在、アクティビティが読み込まれるたびに、リクエストファクトリを使用してデータを取得し(現在はそれほど多くはありませんが、間もなく非常に大きくなります)、ビューに渡してDataGridを更新します。更新される前に、検索ボックスに基づいてフィルタリングされます。

今-私は次のようにDataGridの更新を実装しました:(このコードは最もきれいではありません)

private void updateData() {
  final AsyncDataProvider<EquipmentTypeProxy> provider = new AsyncDataProvider<EquipmentTypeProxy>() {

    @Override
    protected void onRangeChanged(HasData<EquipmentTypeProxy> display) {
      int start = display.getVisibleRange().getStart();
      int end = start + display.getVisibleRange().getLength();
      final List<EquipmentTypeProxy> subList = getSubList(start, end);
      end = (end >= subList.size()) ? subList.size() : end;
      if (subList.size() < DATAGRID_PAGE_SIZE) {
        updateRowCount(subList.size(), true);
      } else {
        updateRowCount(data.size(), true);
      }
      updateRowData(start, subList);
    }

    private List<EquipmentTypeProxy> getSubList(int start, int end) {
      final List<EquipmentTypeProxy> filteredEquipment;
      if (searchString == null || searchString.equals("")) {
        if (data.isEmpty() == false && data.size() > (end - start)) {
          filteredEquipment = data.subList(start, end);
        } else {
          filteredEquipment = data;
        }
      } else {
        filteredEquipment = new ArrayList<EquipmentTypeProxy>();
        for (final EquipmentTypeProxy equipmentType : data) {
          if (equipmentType.getName().contains(searchString)) {
            filteredEquipment.add(equipmentType);
          }
        }
      }
      return filteredEquipment;
    }
  };
  provider.addDataDisplay(dataGrid);
} 

最終的に-私がやりたいのは、最初に必要なデータをロードすることだけです(このアプリケーションのデフォルトのページサイズは25です)。

残念ながら、私の現在の理解では、Google App EngineではIDの順序はありません(1つのエントリのIDは3で、次のエントリのIDは4203です)。

私が疑問に思っているのは、Objectifyを使用しているときにGoogle App Engineからデータのサブセットを取得するための最良の方法は何ですか?

私はオフセットと制限の使用を検討していましたが、別のスタックオーバーフローの投稿(http://stackoverflow.com/questions/9726232/achieve-good-paging-using-objectify)は基本的にこれは非効率的であると述べました。

私が見つけた最高の情報は、次のリンク(http://stackoverflow.com/questions/7027202/objectify-paging-with-cursors)です。ここでの答えは、カーソルを使用することですが、これは非効率的でもあります。私もRequestFactoryを使用しているので、カーソルをユーザーセッションに保存する必要があります(それが正しくない場合はお知らせください)。

現在、大量のデータが存在する可能性は低いため(今後数か月で合計200行になる可能性があります)、一時的なハックとしてセット全体をクライアントにプルバックするだけです-これが最悪の方法であることを私は知っていますしかし、別のハックソリューションを実装する時間を無駄にする前に、それを行うための最良の方法について意見を聞きたいと思います。私がこれを行うことについて読んだすべての投稿が、これを行うための確かな方法が実際にはないように思われるので、私は現在心配しています。

私も考えていること-現在、すべてのデータがすでにクライアント側にあるため、検索/ページの読み込みは非常に高速です。検索ボックスでKeyUpEventハンドラーを使用してデータをフィルタリングします-サーバーを呼び出すことでこの速度を維持する方法はないと思います-この問題に対する受け入れられた解決策はありますか?

どうもありがとうございます

4

1 に答える 1

2

カーソルで移動します。それらはそれが得るのと同じくらい効率的です-カーソルは最後のクエリが終了したポイントを格納し、そこから続行します。リンクした答えは、実際にはカーソルとオフセットの効率については説明していません。(間違ったコメントがあります)

カーソルで制限を使用できます-効率には影響しません。

また、カーソルはRPCを介してシリアル化され、cursor.toWebSafeString()RPCを介してクライアントに送信されます。このように、セッションでそれらを保存する必要はありません。実際には、フラグメント識別子(GWT用語では履歴トークン)としても使用できます。このようにして、結果セットの特定の「ページ」をブックマークできます。

(オフセットは、実際にロードされ、オフセット+制限までのすべてのエンティティに対して課金されるため、「非効率的」です。ビットは、制限エンティティのみを返します)

OTOH、ページがロードされたときにクエリパラメータをすでに知っている場合は、RPCを介して呼び出す代わりに、ページ生成時にクエリを実行します。また、データのセットが少ない場合(<1000)は、ページhtmlの一部であるすべてのエンティティIDをプリロードするだけで済みます。

于 2012-06-12T02:47:57.227 に答える