Playframework Siena过滤和订购

时间:2012-01-10 23:25:11

标签: google-app-engine playframework siena

这是我对这些网站的第一个问题,所以请原谅我的不专业主义。

我将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)。订购也会出现同样的问题。我需要解决这两个问题的方法。

我希望我的问题很清楚,我感谢你们提供任何帮助。

1 个答案:

答案 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

希望这有帮助!