如何在祖先查询上应用日期过滤器

how to apply date filter on ancestor query

我有两个实体模型 Student 和 attendance,这样每个 attendance 实体都有关联的学生家长。

出勤模式:

@Entity
public class Attendance {

 @Id
 Long id;
 @Index
 Date date;
 @Parent
 @Index
 @ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
 Ref<Student> studentRef;

 public Long getId() {
 return id;
 }

 public Date getDate() {
 return date;
 }

 public void setDate(Date date) {
 this.date = date;
 }
 public String getWebsafeKey() {
 return Key.create(studentRef.getKey(), Attendance.class, id).getString();
 }
}

学生模型:

@Entity
public class Student {

 @Id
 Long id;
 @Index
 String name;

 String student_id;

 Long mobile_number;
 String email;

 @Index
 @ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
 List<Ref<Shift>> shiftRef = new ArrayList<Ref<Shift>>();

 public Long getId() {
 return id;
 }

 public String getStudent_id() {
 return student_id;
 }

 public void setStudent_id(String student_id) {
 this.student_id = student_id;
 }

 public String getName() {
 return name;
 }

 public void setName(String name) {
 this.name = name;
 }

 public Long getMobile_number() {
 return mobile_number;
 }

 public void setMobile_number(Long mobile_number) {
 this.mobile_number = mobile_number;
 }

 public String getEmail() {
 return email;
 }

 public void setEmail(String email) {
 this.email = email;
 }

 public String getWebsafeKey() {
 return Key.create(Student.class, id).getString();
 }
}

这是我将考勤实体插入数据存储的方式:

Key<Student> studentKey = Key.create(student_web_safe_key);
Date date = new Date();
date.setTime(System.currentTimeMillis());
attendance.setDate(date);
attendance.studentRef = Ref.create(studentKey);
ofy().save().entity(attendance).now();

问题:

  1. 以上查询将日期存储在数据存储中,格式为:2016-06-15 (18:01:18.845)IST
    但是当我在没有指定其父实体的情况下检索相同的实体时,它给我的日期为:"date ": "2016-06-15T12:31:18.845Z"。请解释一下?

  2. 我可以存储每个学生的出勤率,也可以检索一个学生的所有出勤率。 但是如何检索学生在指定日期或日期范围内的出勤情况? 我试过打击查询: 查询query = ofy().load().type(Attendance.class).ancestor(studentKey).filter("date =",date);

但它给了我以下异常:

com.google.api.client.googleapis.json.GoogleJsonResponseException: 

503 Service Unavailable
    {
      "code": 503,
      "errors": [
        {
          "domain": "global",
          "message": "com.google.appengine.api.datastore.DatastoreNeedIndexException: no matching index found. recommended index is:\n- kind: Attendance\n  ancestor: yes\n  properties:\n  - name: date\n\nThe suggested index for this query is:\n    <datastore-index kind=\"Attendance\" ancestor=\"true\" source=\"manual\">\n        <property name=\"date\" direction=\"asc\"/>\n    </datastore-index>\n\n",
          "reason": "backendError"
        }
      ],
      "message": "com.google.appengine.api.datastore.DatastoreNeedIndexException: no matching index found. recommended index is:\n- kind: Attendance\n  ancestor: yes\n  properties:\n  - name: date\n\nThe suggested index for this query is:\n    <datastore-index kind=\"Attendance\" ancestor=\"true\" source=\"manual\">\n        <property name=\"date\" direction=\"asc\"/>\n    </datastore-index>\n\n"
    }

回答问题 1:

Appengine 使用 UTC 时间戳。因此,您的时间戳将从您的时区转换为 UTC。它仍然是相同的日期和时间。在输出期间,您需要考虑时间戳可能包含时区并相应地格式化/计算本地时间。

回答问题 2:

您的错误中包含了您需要的所有信息。如果你加上

<datastore-index kind="Attendance" ancestor="true" source="manual">
    <property name="date" direction="asc"/>
</datastore-index>

您的 datastore-indexes.xml 您的查询应该有效。 如果该文件尚不存在,请在 src/main/webapp/WEB-INF/datastore-indexes.xml 下创建它,在 web.xmlappengine-web.xml[ 旁边=32=] 文件。 你可以找到一个 example on this page.

至于原因:此错误的答案始终是:因为数据存储需要此查询的复合索引。

只是想根据评论添加到 konqi 的答案中:

如果您将 Cloud Endpoints 与 Android Studio 一起使用,您必须先在导航面板中切换到 "project" 视图,然后导航到您的 "backend" 文件夹,然后是 src->main- >webapp->WEB-INF 然后在该文件夹中您必须手动创建一个数据存储-indexes.xml 文件。这是你的样子:

<?xml version="1.0" encoding="utf-8"?>
<datastore-indexes autoGenerate="true">
    <!-- NOTE: Not necessary to create composite indexes here for single property indices b.c. they are build in.-->

    <!-- If you do not specify direction, default is: direction="asc" -->

    <datastore-index kind="Attendance" ancestor="true" source="manual">
        <property name="date" direction="asc"/>
    </datastore-index>

</datastore-indexes>