今天,一周内和一个月内查询

时间:2013-07-09 16:57:00

标签: java google-app-engine

我是新人。我正在为一个激光标签的地方写一个应用程序,我们有很多年龄的孩子来互相射击。我们正在制作一个高分屏幕,它将显示当天,本周和月份的最佳分数。我们的想法是,人们会为自己被列入名单感到自豪,每个月也会有奖品。

我在整个过滤日期过程中陷入困境。

我基本上修改了经典留言板示例,以便我可以添加分数和客户信息,并按分数对其进行排序。

    Key guestbookKey = KeyFactory.createKey("Guestbook", guestbookName);
    String fornavn = req.getParameter("fornavn");
    Integer score = Integer.parseInt(req.getParameter("score"));
    String email = req.getParameter("email");
    String tlf = req.getParameter("tlf");
    Date date = new Date();
    Entity highscore = new Entity("Greeting", guestbookKey);
    highscore.setProperty("date", date);
    highscore.setProperty("fornavn", fornavn);
    highscore.setProperty("score", score);
    highscore.setProperty("email", email);
    highscore.setProperty("tlf", tlf);

    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
    datastore.put(highscore);

在jsp中有一个查询可以抓住整个前5名。

Query query = new Query("Highscore", highscoreKey).addSort("score", Query.SortDirection.DESCENDING);
List<Entity> greetings = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(5));

还有一个表单将用户输入发送到.java。关于如何设置日期的任何提示?保存周#和月#并根据它查询?看起来很麻烦。

3 个答案:

答案 0 :(得分:1)

据我所知,您的“HighScore”实际上是一种“分数”类型,可以跟踪所有分数。

除了查询本周/月的高分外,您最好还是只需输入一个HighScore实体(与正常的“Score”实体分开),只要您输入分数,就会更新。每次输入新分数时,请检查是否应更新高分。

您永远不需要花哨的查询,只需要获取高分实体。

或者您可能需要为每个月/每周等单独的高分实体,以便您可以跟踪历史记录。在这种情况下,您可能希望将周或月编码为实体密钥,这样您就可以轻松获得当前周/月的HighScore。

答案 1 :(得分:1)

对于像你这样的要求,有两种可能的方法可以显示一天,一周,一个月等的高分:

1,第一个选项是使用当前模型存储日期和分数。由于应用引擎仅允许对1个属性进行不等式过滤,因此您需要在日期应用不等式过滤器,然后找到n个最高分数。但是,由于结果将首先针对具有不等式过滤器的属性进行排序,然后对于任何其他属性,您不能仅对前n个条目进行提取以找到前n个,因为最高分数不需要按连续顺序排列。请参阅this post以更好地理解这一点。因此,您必须获取日期范围的所有分数,然后在客户端进行进一步的查询结果排序,以找到前n个。如果一周或一个月的总分数与n的值相比不会太高,则这种方法是可行的。如果没有,这不是一个可扩展的选项。

2,第二种方法是重新设计您的模型,以便在分数上进行排序,以便在特定时间段内获得前n个分数,您只需要获取前n个条目。这意味着即使分数非常大,该方法也是合适的。然后,这需要将您的日期转换为适合于相等过滤,例如存储月份编号,周数和日历年的每个条目。然后,例如,如果您想在第3个月找到前n个分数,那么您可以查询month=3, sort by scores descending并获取前n个匹配条目。同样,您可以使用周数查询特定周。

答案 2 :(得分:0)

这与另一个高分SO问题非常相似。我在下面复制/粘贴了我的答案。使用数据库查询来接近此解决方案可能会导致您加入抱怨GAE的人员行列。您将使用自定义索引。您的查询可能比每个请求的平均速度慢10x毫秒。您需要索引数千条记录,甚至数百条记录。这会花费你的钱 - 可​​能很多都是:数据存储(索引)和实例,因为你可能是一个高度称为处理函数的高延迟。请多想一点。我的复制/粘贴不是特定于您的设置,但可以轻松扩展。我希望它可能会促使你考虑更低资源,更低成本的替代方案。一如既往...... HTH。 -stevep

以前的高分回答: 您可能想要考虑另一种方法。这是一个很大的索引开销,会导致您的成本更高,执行此函数的处理程序的响应时间会慢一个数量级,并且您将有时间索引更新的最终一致性将影响此数据的维护。如果您有一个繁忙的网站,您肯定不会对与此方法相关的延迟和成本感到满意。

有许多替代方法。您每秒的预期网站交易会影响您选择的内容。这是一个非常简单的选择。使用TextProperty创建一个ndb实体。使用score_userid等字符串序列化最高分数条目。通过将它们与唯一字符连接,将它们存储在文本字段中。当新分数进入时,使用get_by_id检索此记录(ndb会自动为您处理memcaching)。将其拆分为数组。拆分数组的最后一个元素,并检查新的分数。如果它小于分数,则删除它,并将新的score_userid字符串附加到数组。对数组进行排序,连接它,并放入()新的TextProperty。如果你想要你可以设置一天结束时的cron来扫描当天的分数,以检查你的过程是否受到两个分数几乎同时到达而导致一个覆盖另一个分数的极小机会的影响。 HTH。 -stevep

以前的SO高分回答链接:

GAE datastore query with filter and sort using objectify