Swift Vapor Filter с типом поля Массив, содержащий значение

avatar
Farini
8 августа 2021 в 21:06
187
0
1

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

Объект сообщения имеет свойство receivers, которое представляет собой массив UUID, содержащий идентификаторы игроков (в случае, если сообщения отправляются нескольким игрокам).

Как использовать операцию .filter для запроса элементов, в которых массив содержит идентификатор?

Вот мое сообщение Model

final class UserMessage:Model, Content {

    static let schema:String = "messages"

    @ID() var id: UUID?

    // sender
    @Field(key: "sender")
    var sender: UUID

    // receivers
    @Field(key: "receivers")
    var receivers: [UUID]

    @Field(key: "title")
    var title: String

    @Field(key: "body")
    var body: String

    @Field(key: "date")
    var date: Date
}

А вот метод RouteCollection.

func readAllMessages(req:Request) throws -> EventLoopFuture<[UserMessage]> {
    
    // Needs player ID
    guard let pidString = req.parameters.get("pid"),
          let pid = UUID(uuidString: pidString) else {
        throw Abort(.methodNotAllowed)
    }
    
    // FIXME: - Needs to return ONLY where \.receivers:[UUID] contains pid
    
    return UserMessage.query(on: req.db).all().map { messages in
        
        // Is this a too expensive operation?
        var validMessages = messages.filter({ $0.receiver.contains(pid)})
        
        return validMessages
    }
}

Сначала я пытался использовать фильтр ~~, как описано в Vapor Docs здесь

Но это работает только в обратном направлении (коллекция справа).

Я также избегаю создания нескольких реляционных таблиц, чтобы уменьшить количество Content объектов, необходимых приложению. Однако, если это невозможно сделать, я также открыт для другого предложения/решения.

Источник
Leo Dabus
9 августа 2021 в 00:45
1

Мне кажется, это типичный сценарий отношений один-ко-многим. Не знаю, почему вы пытаетесь этого избежать.

Farini
9 августа 2021 в 04:08
0

Я думаю, что это «многие ко многим» (требуется сводная таблица), поскольку игрок может получать много сообщений, а сообщение может иметь много «получателей». Я пытался избежать огромных запросов или слишком большого количества моделей. Но, возможно, это неизбежно. Я думал, что все же спрошу. Вы никогда не знаете, когда кто-то может придумать решение ниндзя. смешной. Если бы это был вопрос HackerRank, я уверен, что кто-нибудь в нем разобрался бы.

0xTim
9 августа 2021 в 11:24
2

Используйте сводную таблицу, это будет намного эффективнее, чем перебирать все сообщения, чтобы найти сообщения для получателя.

Ответы (0)