为了更好地理解数据存储的工作原理,我在项目的HttpServlet类中创建了一个包含多个实体和相关属性的数据存储区。 在创建并填充数据存储区之后,我立即查询它以便将Json对象返回给客户端,以便它可以动态更新其UI。
它有效,但我遇到了一个问题:在我第一次查询数据存储区后,我总是收到不同的排序结果,通常是相同项目的重复项。
这是我的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的建议,将Entity对象统一到同一类型并设置祖先查询之后:
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);
}
这是我得到的结果:
第一次:{{0}}第二次:
编辑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);
}
现在结果正确排序
答案 0 :(得分: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