2015-03-31 94 views
0

爲了更好地理解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); 
    } 

這是結果我得到:

首播時間:first query第二次:second query

編輯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); 
    } 

現在的結果是正確

+2

你必須更精確地得出你得到的結果。數據存儲最終是一致的,所以如果你在添加數據之後立即查詢,這就很正常。 – Patrice 2015-03-31 18:24:20

+2

它看起來像你正在做一個祖先查詢,所以你*應該*獲得強一致性。你能舉一個你看到的例子嗎? – tx802 2015-03-31 19:39:00

+0

看我的編輯。我也注意到,當我將'FetchOptions.Builder.withLimit(9)'設置爲20時,我得到了20個隨機項目,並且有很多重複項目。 – 2015-04-01 09:32:02

回答

1

你的實體分類對象應該遵循相同的模式,如果它們都是相同的類型。

創建同一類型,具有相同的父鍵的不同實體:

Entity tour1 = new Entity("Tour", tourKey); 
Entity tour2 = new Entity("Tour", tourKey); 

填充和上述對象保存到數據存儲之後,你就可以查詢方式:

Query tourQuery = new Query("Tour") 
         .setAncestor(tourKey); 

祖先查詢提供一致性強。 https://cloud.google.com/appengine/docs/java/datastore/queries#Java_Ancestor_queries

+0

謝謝,但它沒有奏效......請參閱我的編輯。 :( – 2015-04-01 09:33:57

相關問題