【问题标题】:Playframework Siena Filtering and OrderingPlayframework Siena 过滤和排序
【发布时间】:2012-01-10 23:25:11
【问题描述】:

这是我在这些网站上的第一个问题,请原谅我的不专业。

我使用带有 SIENA 模块(带有 GAE)的 playframework,我遇到了以下问题: 给定 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 的字段上进行过滤字段(名字)。订购也会出现同样的问题。我需要解决这两个问题。

我希望我的问题很清楚,我很感激这里的任何帮助。

【问题讨论】:

    标签: google-app-engine playframework siena


    【解决方案1】:

    请记住,您在 GAE 中,它是一个 NoSQL 数据库。 所以你不能像在 RDBMS 中那样做加入请求。 然而,这并不是你真正拥有的 pb,所以这只是为了确保你知道它;)

    因此,如果您想查找在给定会议中给出名字的人,您可以尝试以下操作:

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

    (您也可以订购)

    尽管如此,知道您无法加入,但请记住,您不能编写查询来搜索其中有名字为 XXX 的用户的会议,因为它需要一些加入并且它在 GAE 中不存在。在这种情况下,您需要按照 NoSQL 理念更改模型,但这是另一个主题

    问候


    让我们尝试提供一种方法来做你想做的事......

    你的关系是多对多的,这总是最坏的情况:)

    您想按用户的名字过滤会议。
    它需要一个加入请求,这在 GAE 中是不可能的。在这种情况下,您必须通过对模型进行非规范化(有时也使用冗余)来更改模型并自行管理连接。实际上,您必须自己完成 RDBMS 的工作。这看起来有点矫枉过正,但实际上,这很容易。唯一的缺点是您必须对数据库执行多个请求。 NoSQL 意味着 No Schema (& No Join),所以有一些缺点,但它允许扩展和管理巨大的数据负载......这取决于您的需求:)

    您在 GAE 中创建作为“连接”表和一种非规范化的 MeetingUser 的选择很好,因为它允许您自己管理连接。

    解决方案:

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

    希望这会有所帮助!

    【讨论】:

    • 我不知道你所说的加入请求是什么意思。以及 GAE 兼容性的解决方案是什么。正如您所说,您的示例在我的经验中不起作用: meeting.users.asQuery() //returns a Query .filter("firstname","XXX").fetch(); //会产生一个错误,因为 MeetingUser 类没有“名字”字段。
    • join 请求是同时对多个表的请求......经典的 SQL JOIN(您可以在网上找到有关它的信息)
    • 关于我的示例,我以为您想过滤 MeetingUsers 的名字...所以看来我不明白您想要什么...
    • 如果您查看问题中的示例代码,您会看到 MeetingUser 类是一个表,用于表示会议和用户之间的多对多关系,它只有两个字段:用户用户和会议会议。该类中没有名字字段。我想查询会议的所有 MeetingUser 实体(meeting.users.asQuery()),然后根据 meetingusers 实例的用户字段中的名字对其进行过滤。这清楚知道吗?对不起,如果不是,我会再次尝试解释。
    • 好吧,我明白了……在这种情况下,它看起来像一个 JOIN 请求,但你不能在 GAE 中这样做。您不能从 MeetingUser 中选择并在同一请求中过滤 User。
    猜你喜欢
    • 2011-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-14
    • 2020-05-27
    • 2019-12-30
    • 2023-04-04
    • 2021-03-31
    相关资源
    最近更新 更多