爲了更好地理解Datastore的工作原理,我在項目的HttpServlet類中創建了一個包含多個實體和相關屬性的數據存儲。 創建並填充數據存儲之後,我立即查詢它以便將Json對象返回給客戶端,以便它可以動態更新其UI。App Engine數據存儲查詢結果隨機返回
它的工作原理,但我有一個問題:我第一次查詢數據存儲後,我總是收到不同的排序結果,往往與重複相同的項目。
這是我的HttpServlet代碼:
public class MyServlet extends HttpServlet {
ArrayList<Tour> m_tours = new ArrayList<Tour>();
Key tourKey;
DatastoreService datastore;
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
//nothing special here
}
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
populateDatastore();
String asyncMessage = req.getParameter("order");
if(asyncMessage.equals("tours")){
m_tours = getTours();
}
if(asyncMessage.equals("selectTour")){
}
Tours tours = new Tours(m_tours);
resp.setContentType("application/json");
PrintWriter out = resp.getWriter();
out.print(new Gson().toJson(tours));
out.flush();
}
private DatastoreService populateDatastore(){
datastore = DatastoreServiceFactory.getDatastoreService();
tourKey = KeyFactory.createKey("availabletours", "tours"); //parent
Entity tour = new Entity("tour", tourKey);
tour.setProperty("tourname", "Tour0");
tour.setProperty("tourinfo", "info0");
datastore.put(tour);
Entity tour1 = new Entity("tour1", tourKey);
tour1.setProperty("tourname", "Tour 1");
tour1.setProperty("tourinfo", "info 1");
datastore.put(tour1);
//..... and so on
return datastore;
}
private ArrayList<Tour> getTours(){
ArrayList<Tour> toursArray = new ArrayList<Tour>();
Query query = new Query(tourKey);
List<Entity> tourss = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(9));
for (Entity t : tourss) {
String tourname=t.getProperty("tourname").toString();
String tourinfo=t.getProperty("tourinfo").toString();
Tour ts = new Tour(tourname,tourinfo);
toursArray.add(ts);
}
return toursArray;
}
}
我在做什麼錯?管理數據存儲的最佳方式是什麼?
*編輯*
均勻化實體對象相同類型和設置一個祖先查詢,如建議通過@Jeff Deskins後:
datastore = DatastoreServiceFactory.getDatastoreService();
tourKey = KeyFactory.createKey("availabletours", "tours"); //parent
Entity tour = new Entity("tour", tourKey);
tour.setProperty("tourname", "Tour0");
tour.setProperty("tourinfo", "info0");
datastore.put(tour);
Entity tour1 = new Entity("tour", tourKey);
tour1.setProperty("tourname", "Tour 1");
tour1.setProperty("tourinfo", "info 1");
datastore.put(tour1);
//... ... same way with the others
我設置祖先查詢:
Query query = new Query("tour").setAncestor(tourKey);
List<Entity> tourss = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(9));
for (Entity t : tourss) {
String tourname=t.getProperty("tourname").toString();
String tourinfo=t.getProperty("tourinfo").toString();
Tour ts = new Tour(tourname,tourinfo);
toursArray.add(ts);
}
這是結果我得到:
首播時間:第二次:
編輯2:答案 - 除了執行祖先查詢,我還需要申請排序查詢。因此,解決方案是將屬性添加到每個實體:
Entity tour = new Entity("tour", tourKey);
tour.setProperty("tourname", "Tour 1");
tour.setProperty("tourinfo", "info 1");
tour.setProperty("order","0");
Entity tour = new Entity("tour", tourKey);
tour.setProperty("tourname", "Tour 2");
tour.setProperty("tourinfo", "info 2");
tour.setProperty("order","1");
,然後應用排序過濾器來查詢:
ArrayList<Tour> toursArray = new ArrayList<Tour>();
Query query = new Query("tour").setAncestor(tourKey).addSort("order");
List<Entity> tourss = new ArrayList<Entity>();
tourss = datastore.prepare(query).asList(FetchOptions.Builder.withDefaults());
for (Entity t : tourss) {
String tourname=t.getProperty("tourname").toString();
String tourinfo=t.getProperty("tourinfo").toString();
Tour ts = new Tour(tourname,tourinfo);
toursArray.add(ts);
}
現在的結果是正確
你必須更精確地得出你得到的結果。數據存儲最終是一致的,所以如果你在添加數據之後立即查詢,這就很正常。 – Patrice 2015-03-31 18:24:20
它看起來像你正在做一個祖先查詢,所以你*應該*獲得強一致性。你能舉一個你看到的例子嗎? – tx802 2015-03-31 19:39:00
看我的編輯。我也注意到,當我將'FetchOptions.Builder.withLimit(9)'設置爲20時,我得到了20個隨機項目,並且有很多重複項目。 – 2015-04-01 09:32:02