Playframework Siena Фильтрация и заказ - PullRequest
0 голосов
/ 11 января 2012

Это мой первый вопрос на любом из этих сайтов, так что извините за непрофессионализм.

Я использую игровую рамку с модулем 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, так как мне нужно фильтровать поле поля MeetingUser (firstName).Та же проблема возникает при заказе.Мне нужно решение обеих проблем.

Я надеюсь, что моя проблема ясна, и я ценю любую помощь здесь.

1 Ответ

0 голосов
/ 11 января 2012

Помните, что вы находитесь в GAE, который является NoSQL DB. Таким образом, вы не можете сделать запрос на присоединение, как в RDBMS. Тем не менее, это не совсем то, что у вас есть, так что это было просто, чтобы убедиться, что вы знаете об этом;)

Так что, если вы хотите найти человека, который дал имя на данной встрече, вы можете попробовать следующее:

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

(вы также можете заказать)

Тем не менее, зная, что вы не можете присоединиться, помните, что вы не можете написать запрос, ищущий собрание, в котором есть пользователи, чье имя - XXX, так как для этого требуется несколько объединений, и его нет в GAE. В этом случае вам нужно изменить модель в соответствии с философией NoSQL, но это уже другая тема

1010 * привет *


Давайте попробуем дать способ сделать то, что вы хотите ...

Ваше отношение «многие ко многим», что всегда является наихудшим случаем:)

Вы хотите отфильтровать собрание по имени пользователя.
Требуется запрос на присоединение, который невозможен в GAE. В этом случае вы должны изменить свою модель путем ее денормализации (иногда также используйте избыточность) и самостоятельно управлять объединением. На самом деле, вы должны выполнять работу СУБД самостоятельно. Это кажется излишним, но на самом деле это довольно просто. Единственным недостатком является то, что вы должны выполнить несколько запросов к БД. NoSQL означает No Schema (& No Join), поэтому есть несколько недостатков, но он позволяет масштабировать и управлять огромной загрузкой данных ... это зависит от ваших потребностей:)

Выбор, который вы сделали для создания 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

Надеюсь, это поможет!

...