简体   繁体   English

Playframework Siena筛选和订购

[英]Playframework Siena Filtering and Ordering

This is my first question on any of these websites so pardon my unprofessionalism. 这是我在任何这些网站上遇到的第一个问题,请原谅我的非专业精神。

I use playframework with SIENA module (with GAE) and I came accross the following problem: Given 3 entities: 我将播放框架与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();
    }

}

For instance I am listing a meeting and all their users: 例如,我列出了一个会议及其所有用户:

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);
}

This is done(is there any better way here?) however when it comes to filtering (especially dynamic filtering for many many fields) I can not use the Query's filter method on the MeetingUser as I need to filter on a MeetingUser's field's field (firstName). 做到了(这里还有更好的方法吗?)但是,当涉及到过滤(尤其是许多字段的动态过滤)时,我无法在MeetingUser上使用查询的filter方法,因为我需要在MeetingUser的字段的字段(firstName)上进行过滤)。 The same problem arise for ordering. 订购会出现相同的问题。 I need the solution for both problems. 我需要两个问题的解决方案。

I hope my problem is clear and I appreciate any kind of help here. 我希望我的问题很清楚,在此感谢我的任何帮助。

Remember that you are in GAE which is a NoSQL DB. 请记住,您在GAE(这是一个NoSQL DB)中。 So you can't do Join request as in RDBMS. 因此,您不能像在RDBMS中那样执行Join请求。 Yet, this is not really the pb you have so this was just to be sure you are aware of it ;) 但是,这实际上并不是您拥有的铅,因此只是为了确保您知道它;)

So if you want to find the person having given firstname in a given meeting, can you try the following: 因此,如果您想在给定的会议中找到拥有名字的人,可以尝试以下方法:

List<MeetingUser> meetingusers = meeting.users.asQuery().filter("firstname", "XXX"); 

(you can also order) (您也可以订购)

Nevertheless, knowing that you can't join, remember that you can't write a query searching for a meeting in which there are users whose firstname is XXX as it would require some joins and it doesn't exist in GAE. 但是,知道您无法加入后,请记住,您无法编写查询来搜索其中有用户的名字为XXX的用户的会议,因为这将需要一些加入并且在GAE中不存在。 In this case, you need to change your model following NoSQL philosophy but this is another subject 在这种情况下,您需要遵循NoSQL原理更改模型,但这是另一个主题

regards 问候


Let's try to give a way to do what you want... 让我们尝试给出一种方法来做您想要的...

Your relation is a Many-to-Many which is always the worst case :) 您的关系是多对多,这总是最坏的情况:)

You want to filter Meeting by User's firstname. 您要按用户的名字过滤会议。
It requires a join request which is not possible in GAE. 它要求加入请求,这在GAE中是不可能的。 In this case, you must change your model by denormalizing it (sometimes use redundancy also) and manage the join by yourself. 在这种情况下,您必须通过对模型进行规范化来更改模型(有时也使用冗余),并自行管理连接。 Actually, you must do the job of the RDBMS by yourself. 实际上,您必须自己完成RDBMS的工作。 It seems overkill but in fact, it's quite easy. 似乎有点杀伤力,但实际上,这很容易。 The only drawback is that you must perform several requests to the DB. 唯一的缺点是必须对数据库执行多个请求。 NoSQL means No Schema (& No Join) so there are a few drawbacks but it allows to scale and to manage huge data load... it depends on your needs :) NoSQL表示没有模式(&不加入),因此存在一些缺点,但是它允许扩展和管理巨大的数据负载...这取决于您的需求:)

The choice you did to create the MeetingUser which is a "joined" table and a kind of denormalization is good in GAE because it allows to manage the join yourself. 在GAE中,您最好选择创建MeetingUser(这是一个“联接”表)并进行某种非规范化,因为它允许您自己管理联接。

Solution: 解:

// 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

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM