【问题标题】:how to apply date filter on ancestor query如何在祖先查询上应用日期过滤器
【发布时间】:2016-10-17 13:41:08
【问题描述】:

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

出勤模式:

@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 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"
    }

【问题讨论】:

    标签: google-app-engine objectify google-cloud-datastore


    【解决方案1】:

    回答问题 1:

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

    回答问题 2:

    您在错误中拥有所需的所有信息。如果你添加

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

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

    至于为什么:这个错误的答案总是:因为数据存储需要一个复合索引来进行这个查询。

    【讨论】:

    • 感谢@konqi 的评论...我搜索了很多,但我没有找到我的android 工作室的datastore-indexes.xml 文件。你能告诉我这个文件在 android studio 中的位置吗?
    • datastore-indexes.xml 实际上是一个链接。单击它,您会发现该文件应该在WEB-INF文件夹中,与您的web.xml和appengine-web.xml所在的位置相同。
    • 这个链接在android studio的什么位置?
    • 我的意思是我的答案中的链接,网址是:cloud.google.com/appengine/docs/java/config/indexconfig
    • @Baqir 查看我的回答我发布了一些关于您需要使用 Android Studio + Cloud Endpoints 做什么的代码
    【解决方案2】:

    只是想根据cmets补充konqi的答案:

    如果您在 Android Studio 中使用 Cloud Endpoints,您必须先在导航面板中切换到“项目”视图,然后导航到“后端”文件夹,然后导航到 src->main->webapp->WEB-INF,然后在您必须手动创建一个 datastore-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>
    

    【讨论】:

    • 我无法决定是否将其标记为“不是答案”,因为它不会自行回答问题。它应该被评论和/或改进为独立和/或欢迎您编辑我的答案。
    • @konqi 我相信如果“答案”可以帮助困惑的人(包括 OP 和未来的读者),那么它应该站得住脚。使用 Cloud Endpoints + Google App Engine 的这一领域的文档记录很少,初学者会感到很困惑。随意将其添加到您的答案中,我将删除我的,哈哈 =) 我不介意
    • 嗯,这个问题与 Cloud Endpoints 无关,而索引实际上是记录较好的特性之一。尝试找出如何在 Cloud Endpoints 中实施自定义身份验证器,这将是文档不足的。我对您的回答的主要问题是它回答了问题中未提出的问题。该操作不要求 Android Studio。这个问题来自 cmets 到我的回答,所以要理解你的问题,必须先阅读 cmets。当我删除我的答案时,您的答案毫无意义。你认为这会让事情变得不那么混乱吗?我很好。
    • @konqi 所以解决方案是让 OP 指定他正在使用 android studio(他是),让我删除我的问题并将我的答案附加到你的问题上。我这样做完全没问题,但我敢打赌,我、你和 OP 都懒得这样做,所以未来来到这个页面的人将不得不做一些寻宝游戏 =P(具有讽刺意味的是,我们不太懒惰只发表评论来回大声笑)
    • shrug 我将您答案的精髓添加到我的答案中,这基本上就是完整的路径。我不做 IDE 指令,我喜欢保持我的答案通用,以便它们适用于每个人。如果有人(甚至)没有能力处理所选的开发环境,我不愿意提供帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 1970-01-01
    • 2012-09-13
    • 2017-10-26
    • 1970-01-01
    • 2010-12-23
    • 1970-01-01
    相关资源
    最近更新 更多