2013-07-09 68 views
2

我是新來的。我正在爲一個激光標籤的地方寫一個應用程序,我們已經有很多年齡的孩子來拍攝對方的光束。我們製作的高分屏幕將顯示當天,本週和本月的最佳分數。這個想法是,人們會爲名單感到自豪,並且每個月還會有一次獎品。今天,一週內和一個月內查詢

我陷在了日期事件的整個過濾中。

我基本上修改了經典留言簿示例,以便我可以添加分數和客戶信息,並按分數對其進行排序。

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的形式查詢。我應該如何設置日期的任何提示?節省周#和月#並根據這個查詢?看起來很麻煩。

+0

+1激光標記。真棒! – iamnotmaynard

回答

1

從我所知道的情況來看,你的「HighScore」類實際上是一種記錄所有分數的「分數」類。

而不是查詢周/月的高分,您可能最好擁有一個單一的HighScore實體(與正常的「分數」實體分開),每次輸入分數時都會更新。每次輸入新分數時,檢查是否應更新高分。

你永遠不需要一個奇特的查詢,你只需要獲取高分實體。

或者您可能需要每個月/周等單獨的高分實體等,以便您可以跟蹤歷史記錄。在這種情況下,您可能想要將周或月編碼到實體關鍵字中,以便您輕鬆獲取當前的周/月份HighScore。

1

有像您希望顯示一天,一週,一個月高分你等要求2種可能的方法:

1,第一種選擇是使用當前的模型,其中要存儲日期和得分了。由於應用引擎只允許對1個屬性進行不等式過濾,因此您需要在日期上應用不等式過濾器,然後查找n個最高分數。但是,由於結果將首先針對具有不等式過濾器的屬性進行排序,然後針對任何其他屬性進行排序,因此無法僅爲前n個條目執行提取以查找前n個,因爲頂部得分不必連續排序。請參閱this post以更好地理解此內容。因此,您必須獲取日期範圍內的所有分數,然後在客戶端進一步對查詢結果進行排序以找到最前面的n。如果一週或一個月的總分數與n的值相比不會太高,則這種方法是可行的。如果不是,這不是一個可擴展的選項。

2,第二種方法是重新設計您的模型,以便在分數上進行排序,以便在特定時間段內獲得排名前n的分數,您只需要提取前n個條目。這意味着即使分數非常大,該方法也適用。這就要求將日期轉換爲適合於存儲月份編號,周編號和日曆年的每個條目的平等過濾。然後,例如,如果您想在第3個月查找前n個分數,則可以查詢month=3, sort by scores descending並獲取前n個匹配條目。同樣,您可以使用一週數字查詢特定的一週。

0

這與另一個高分問題非常相似。我在下面複製/粘貼了我的答案。使用數據庫查詢來接近這個解決方案可能會導致您加入抱怨GAE的人羣。您將使用自定義索引。您的查詢可能平均比每個請求所需的速度慢10倍。你將需要索引數千,甚至數百萬條記錄。這會花費你的錢 - 可​​能很多都是:數據存儲(索引)和實例,因爲你的高延遲可能是一個高度稱之爲處理函數。請考慮不同。我的複製/粘貼不是特定於您的設置,但它可以輕鬆地輕鬆擴展。我希望這可能會促使你考慮更低的資源,更低的成本選擇。一如既往...... HTH。 -stevep

上一個高分回答: 您可能想要考慮一種替代方法。這會導致很多索引開銷,這會導致您的開銷更高,執行此函數的處理程序的響應時間會較慢地運行一個數量級,您將有時會發現索引更新的最終一致性會影響此數據的維護。如果你有一個繁忙的網站,你肯定不會對這種方法的延遲和成本感到滿意。

有許多替代方法。您每秒預計的網站交易將影響您選擇的網站。這是一個非常簡單的選擇。用TextProperty創建一個ndb實體。使用諸如score_userid之類的字符串序列化最高分數條目。通過將它們與唯一字符結合,將它們存儲在文本字段中。當新分數進來時,使用get_by_id檢索此記錄(ndb會自動爲您處理memcaching)。將其拆分成一個數組。拆分數組的最後一個元素,並檢查新的分數。如果它小於分數,請將其刪除,然後將新的score_userid字符串附加到數組中。對數組進行排序,將其加入並放入()新的TextProperty。如果你希望你可以設置一天的結束時間來掃描你的分數,以檢查你的過程是否受到兩個分數幾乎同時到達導致一個覆蓋另一個分數的非常小的機會的影響。 HTH。 -stevep

上一頁SO高分答案鏈接:

GAE datastore query with filter and sort using objectify

相關問題