gpt4 book ai didi

java - GAE Objectify如何将查询结果用于另一个查询

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:42:09 25 4
gpt4 key购买 nike

这道题的基本思路如下。我执行一些查询

      List<Class2> class2entities = ObjectifyService.ofy()
.load()
.type(Class2.class)
.filter(?,?)
.list();

我可以用什么方式执行另一个基于 class2entities 的查询?

实际上,我正在开发基于 Objectify 的 GAE 应用程序。我使用以下实体

问题:

 @Entity
public class Problem {
@Id public String problemname;

public Problem (String name) {
problemname = name;
}

public Problem () {
problemname = "nullProblem";
}
}

元组:

    @Entity
public class Tuple {
@Parent Ref<Problem> theProblem;
@Index public String tuple_id;
@Id public Long id;

public Tuple()
{
String s="empty operator";
}

public Tuple(String sid, Problem problem)
{
tuple_id = sid;
try {
theProblem = Ref.create(problem);
}
catch (java.lang.NullPointerException e)
{
System.out.println(e.toString() + " tuple in datastore was not created because of Problem is empty" );
}
}
}

属性:

@Entity
public class Attribute {
@Parent com.googlecode.objectify.Ref<Problem> theProblem;
@Id public Long id;

public String attributeName;
@Index public String attributeFieldName;
@Index public Date date;

/**
* Simple constructor just sets the date
**/
public Attribute() {
date = new Date();
}

/**
* A connivence constructor
**/
public Attribute(Problem problem, String attributeName) {
this();
if( problem != null ) {
theProblem = Ref.create(problem); // Creating the Ancestor key
} else {
theProblem = Ref.create(new Problem("nullProblem"));
}
this.attributeName = attributeName;
}

/**
* Takes all important fields
**/
public Attribute(Problem problem, String attributeName, String var_attributeFieldName) {
this(problem, attributeName);
attributeFieldName = var_attributeFieldName;
}

}

分类数据:

@Entity
public class CategorizedData {
@Load public Ref<Attribute> theAttribute;
@Id Long id;
@Parent public Key<Tuple> theTuple;
public String attributeValue;

@Index public Date date;


/**
* getter and setter for theAttribute
**/

public Attribute getAttribute() { return theAttribute.get(); }
public void setAttribute(Attribute attribute) { theAttribute = Ref.create(attribute); }

/**
* Simple constructor just sets the date
**/
public CategorizedData() {
date = new Date();
}

/**
* A connivence constructor
**/
public CategorizedData(String tupleId, String attribute_field_name, String var_attributeValue) {
this();
Attribute attribute = ofy().load().type(Attribute.class).filter("attributeFieldName", attribute_field_name).first().now();
Tuple tuple = ofy().load().type(Tuple.class).filter("tuple_id",tupleId).first().now();

if( tupleId != null ) {
theTuple = Key.create(Tuple.class, tuple.id); // Creating the Ancestor key
} else {
theTuple = Key.create(Tuple.class, (new Tuple()).id);
}
if( attribute != null ) {
theAttribute = Ref.create(attribute); // Creating the Ancestor ref
} else {
theAttribute = Ref.create(new Attribute());
}
this.attributeValue = var_attributeValue;
}

}

现在我想获取给定问题的所有元组实体,并获取具有给定 AttributeFieldName 的属性字段的 CategorizedData 的所有实体。

我需要做类似的事情

Key<Problem> theProblem = Key.create(Problem.class, problemName);
// Run an ancestor query
List<Tuple> tuples = ObjectifyService.ofy()
.load()
.type(Tuple.class)
.ancestor(theProblem)
.list();

然后我需要在此列表元组中获取 CategorizedData 的实体。我应该怎么办?是否可以将先前查询的结果用于 Objectify 查询而不是所有数据存储?请帮助我...

最佳答案

您的问题有几个解决方案。但首先我想说您的实体可能针对数据存储设计不佳。使用数据存储时,您应该通过分析要查询的内容来创建实体。

一个例子:

你有一个 Problem实体和一个Tuple实体但你的Problem实体只有一个属性 ( problemname )。数据存储方式是非规范化这种关系并将 problemname属性到你的 Tuple实体(或 Tuple 属性到 Problem )。这样你就可以开始查询你的 Tuple entitiy 并且您已经拥有正式两个实体的数据。是的,这意味着您的数据存储中将有冗余数据,但从数据存储的角度来看这很好。

现在来解决你的实际问题

Objectify 允许您设置 @LoadRef<Something> 的注释. Objectify 将对此做的是

  1. 查询实体
  2. 如果为实体的其中一个属性定义了@Load,则该属性的值将放入列表中
  3. Objectify 做了一个 load().keys(<ListFrom2>)
  4. 您现在可以使用 Ref#get() - 方法及其背后的实体已经加载

因此您可以使用 @Load 注释,但即使您不需要它们,它也会始终加载 Refs。我通常自己创建一个加载数据的方法。基本上我实现了 1-4 中的所有步骤,除了没有 @Load 注释并且我的方法创建了键列表来加载自身。这里唯一的问题是将结果 Entities 匹配回 Ref(实际上这不是一个大问题,因为以集合作为参数的键查询的结果是一个以实体键作为键的 Map)

其次,如果你想/必须保持你的实体那样。尝试减少对数据存储的调用量并在内存中进行一些排序:

ofy.load().ancestor(Key.create(Problem.class, "ProblemName"))

会给你Problem和所有相关的Tuple s 和 Attribute秒。如果您需要 CategorizedData同样,制作CategorizedData Problem 的 child 并引用 Attribute用一个简单的 Ref<Attribute>没有@Parent。再说一次:如果这是我的代码,我会制作 CategroizedData嵌入式 ListAttribute .在处理祖先查询的结果时,您可以自己进行各种过滤和排序。这比执行数百个查询要快得多。

总而言之,我认为您的问题源于在设计实体时没有考虑数据的实际使用。尽可能去规范化,将冗余数据视为一种选择,而不是不可行的。

关于java - GAE Objectify如何将查询结果用于另一个查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32139350/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com