这是我对这些网站的第一个问题,所以请原谅我的不专业主义。
我将playframework与 SIENA 模块(使用GAE)一起使用,我遇到了以下问题: 鉴于3个实体:
public class Meeting extends Model{
@Id
public Long id;
public String place;
@Owned
Many<MeetingUser> users;
.
.
.
}
public class User extends Model{
@Id
public Long id;
public String firstName;
public String lastName;
@Owned
Many<MeetingUser> meetings;
.
.
.
}
public class MeetingUser extends Model{
@Id
public Long id;
public Meeting meeting;
public User user;
.
.
.
public User getUser(){
return Model.all(User.class).filter("id", user).get();
}
public Meeting getMeeting(){
return Model.all(Meeting.class).filter("id", meeting).get();
}
}
例如,我列出了一个会议及其所有用户:
public static void meetingInfo(Long meetingId){
Meeting meeting = Models.all(Meeting.class).filter("id",meetingId);
List<MeetingUser> meetingusers = meeting.asList();
List<User> users = new ArrayList<User>();
for(MeetingUser mu: meetingusers){
users.add(mu.getUser());
}
render(users);
}
这已经完成了(这里有更好的方法吗?)但是当涉及到过滤(特别是许多字段的动态过滤)时,我不能在MeetingUser上使用Query的过滤方法,因为我需要在MeetingUser的字段上过滤field(firstName)。订购也会出现同样的问题。我需要解决这两个问题的方法。
我希望我的问题很清楚,我感谢你们提供任何帮助。
答案 0 :(得分:0)
请记住,您在GAE中是NoSQL DB。 所以你不能像在RDBMS中那样做Join请求。 然而,这不是你所拥有的,所以这只是为了确保你知道它;)
因此,如果您想在特定会议中找到给出名字的人,可以尝试以下方法:
List<MeetingUser> meetingusers = meeting.users.asQuery().filter("firstname", "XXX");
(您也可以订购)
尽管如此,知道你无法加入,请记住,你不能编写一个查询来搜索其名字为XXX的用户的会议,因为它需要一些联接而GAE中不存在。在这种情况下,您需要根据NoSQL哲学更改模型,但这是另一个主题
问候
让我们试着想办法做你想做的事......
你的关系是多对多的,这总是最糟糕的情况:)
您想要按用户的名字过滤会议 它需要加入请求,这在GAE中是不可能的。在这种情况下,您必须通过对其进行非规范化来更改模型(有时也使用冗余)并自行管理连接。实际上,您必须自己完成RDBMS的工作。这似乎有点矫枉过正,但事实上,这很容易。唯一的缺点是您必须对数据库执行多个请求。 NoSQL意味着没有架构(并且没有加入),因此存在一些缺点,但它允许扩展和管理大量数据负载......这取决于您的需求:)
您在创建MeetingUser时所做的选择是一个“联合”表和一种非规范化在GAE中很好,因为它允许自己管理联接。
解决方案:
// fetch users by firstname
List<User> users = users.all().filter("firstName", "John").fetch();
// fetch meetingusers associated to these users (verify the "IN" operator works because I didn't use that for a long time and don't remember if it works with this syntax)
List<MeetingUser> meetingusers = MeetingUser.all().filter("user IN", users);
// now you must fetch the whole meeting because in MeetingUser, only the Meeting ID is stored (other fields are Null or O)
List<Meeting> meetings = new ArrayList<Meeting>()
for(MeetingUsers mu:meetingusers) {
meetings.add(meetingusers.meeting);
}
// use the batch feature to fetch all objects
Meeting.batch(Meeting.class).get(meetings);
// you have your meetings
希望这有帮助!