在 Google App Engine 数据存储区中获取一个不属于列表的随机实体 [英] Get a random entity in Google App Engine datastore which does not belong to a list

查看:30
本文介绍了在 Google App Engine 数据存储区中获取一个不属于列表的随机实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Google App Engine 构建网络游戏.游戏有一个存储的用户创建的关卡列表(可能很多,并且动态增加),每个用户都有一个他已经玩过的关卡列表.我需要为一个他以前没有玩过的用户随机选择一个级别.实体建模如下:

I am using Google App Engine to build a web game. The game has a list of stored user-created levels (which may be a lot, and dynamically increasing as well), and each user has a list of levels which he has played already. I need to randomly pick up a level for a user which he has not played before. The Entities are modeled like this:

class User(ndb.Model):
    uid = ndb.StringProperty()
    levels_played = ndb.KeyProperty(kind='Level', repeated=True)

class Level(ndb.Model):
    #some stuff here

所以基本上我需要执行一个查询,给定一个uid,选择一个不属于相应列表levels_played的随机关卡.执行此操作的最有效方法是什么?

So basically I need to perform a query which, given a uid, chooses a random Level which does not belong to the corresponding list levels_played. What would be the most efficient way to do this?

推荐答案

没有简单的方法,因为您无法以符合您要求的方式进行连接.

There will be no easy way as you cannot do a join in a way that will perform for you requirement.

查看此处选择随机记录的策略.

Have a look at the strategies here for selecting a random record.

在ndb中查询随机行

就我个人而言,我会从范围键中随机选择 id,然后获取下一个 n 记录选项.然后检查提取的n条记录中的选择是否不在播放记录列表中.如果是从 n 个记录的列表中选择不同的级别.

Personally I would go for the randomly chosen id from a range key then fetch the next n records option. And then check that the choice from the n records fetched is not in the list of played records. If it is pick a different level from that list of n records.

但是,一旦您有大量播放的记录,即使这样也无法很好地扩展,除非您保留一个二进制的键块,以便您可以快速检查是否有人玩过关卡.

However even this won't scale well once you have large numbers of played records, unless you keep a binary blob of keys, that you can quickly check if a level has been played against.

您合理期望拥有多少级别和多少玩家.一旦级别和玩家数量增加,您可能不得不用性能来换取大量内务数据以提高性能.

How many levels and how many players do you reasonably expect to have. You will probably have to trade off performance for a lot of house keeping data to get the performance up once the set of levels and players grows.

另一种方法是使用 allocids(以获得顺序 ID)作为级别并构建位图.维护一个全局位图,为每个已创建的级别 id 设置一个位,然后为每个用户设置一个位图,为播放的级别设置每个位.您可以在一个 1MB 的 blob 属性中存储大约 800 万个级别.进行一些操作,您就可以从一组未玩过的游戏中进行选择.选择一点,然后获取级别.

An alternative approach would be to use allocids (to get sequential id's) for levels and build bitmaps. Maintain a global bitmap with a bit set for each level id that has been created and then a bitmap for each user setting each bit for a level played. You could store around 8million levels in a single 1MB blobproperty. A few bit operations and you have the set of unplayed games to choose from. Pick a bit, and fetch the level.

这篇关于在 Google App Engine 数据存储区中获取一个不属于列表的随机实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆