1

タイプClubを持つa をモデル化する必要があります。明らかに、クラブには膨大な数のメンバーがいる可能性があります。membersUser

私はこれをやった

class User(EndpointsModel):
    username = ndb.StringProperty(required=True)


class Club(EndpointsModel):
    ....
    members_key = ndb.KeyProperty(kind="User", repeated=True)

    @EndpointsAliasProperty(repeated=True,property_type=User.ProtoModel())
    def members(self):
        return ndb.get_multi(self.members_key)

応答でこのように実行すると、ユーザーのリスト全体が取得されます。これには、5000 人のメンバーがいる場合、しばらく時間がかかることがあります。

このリストを改ページする可能性はありますか? ProtoCollection()の代わりに使用する可能性がありProtoModel()ますか?(私は成功せずに試しました)。

/club/{id}/membersまたは、メンバーのリスト (ページ付けされた) を返すタイプのエンドポイントを作成するにはどうすればよいですか?

4

2 に答える 2

1

多くのユーザーと1つのクラブの関係を実装する方法は他にもたくさんあります.ユーザーがメンバーであるクラブを参照する「クラブ」の繰り返しプロパティをユーザーに格納することを考えました(クラブのキーを格納します)。clubs プロパティを満たすユーザーに対してクエリを実行し、結果をページ サイズに制限します。のようなパターンを使用します

next_page_results = User.all().filter('club =', club_key).filter('__key__ >', last_seen_key).order('key').run(limit=page_size)

ページが正しく取得され、正しい場所で開始および停止されるようにする

last_seen_key = next_page_results[-1]次の電話の場所)

あなたがやっている方法では、毎回すべての結果を取得し、メモリ内でフィルタリングします。これはまずいですし、お金もかかります。

于 2014-12-13T23:35:32.497 に答える
1

私はここにいます。私はいくつかのテストを行い、この解決策を見つけました(メソッドをclub/{id}/members

標準エンドポイント用のリソース コンテナーを作成しました。メッセージは、 が入力として持っているものをコピーquery_methodします。

ID_RESOURCE_PAGE = endpoints.ResourceContainer(
    message_types.VoidMessage,
    id=messages.IntegerField(1, variant=messages.Variant.INT64),
    cursor=messages.StringField(2, variant=messages.Variant.STRING, required=False, default="1"),
    limit=messages.IntegerField(3, variant=messages.Variant.INT32, required=False, default=10)
)

@endopint.method次に、このような標準を作成しました

@endpoints.method(ID_RESOURCE_PAGE, User.ProtoCollection(),
                      path='club/{id}/members',
                      http_method='GET',
                      name='club.members')
    def club_memebers(self, request):
        # check if user has ownership
        club = Club.get_by_id(request.id)
        page_size = request.limit
        # convert the cursors, usually it's a token, here is page number.
        page = int(request.cursor)
        # internal check, just in case.
        if (page is None or page < 0):
            raise endpoints.BadRequestException(message="Page field must be a positive integer")
        if (page_size is None or page_size < 0 or page > 100):
            raise endpoints.BadRequestException(
                message="Page_size field must be a positive integer and cannot be greater than 100")
        # compute start and end users to retrive
        start = (page - 1) * page_size
        end = page * page_size
        # crop the list
        res_list = club.membersUser[start:end]
        # create the object
        ret = User.ToMessageCollection(res_list)
        # it's probably another page
        if (len(res_list) == page_size):
            # add next page as nextPageToken, not the best but the easy way
            ret.nextPageToken = str(page + 1)
        return ret

User.ProtoCollection()以前はコレクションを自動的にシリアル化し、ページ番号を偽造していたことに注意してくださいret.nextPageToken。この最後の編集はあまりきれいに見えませんが (実際にはそうではありません)、クエリは機能します。

それでも、私はこのソリューションに本当に満足していません。

于 2014-10-27T07:38:55.693 に答える