0

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

我使用带有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 上使用查询的过滤方法,因为我需要过滤 MeetingUser 的字段(firstName )。订购也会出现同样的问题。我需要解决这两个问题。

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

4

1 回答 1

0

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

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

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

(您也可以订购)

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

问候


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

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

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

您在 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

希望这可以帮助!

于 2012-01-11T14:13:04.580 回答