Я пытаюсь создать метод, с помощью которого игроки могут получать свои сообщения в игре.
Объект сообщения имеет свойство 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
объектов, необходимых приложению. Однако, если это невозможно сделать, я также открыт для другого предложения/решения.
Мне кажется, это типичный сценарий отношений один-ко-многим. Не знаю, почему вы пытаетесь этого избежать.
Я думаю, что это «многие ко многим» (требуется сводная таблица), поскольку игрок может получать много сообщений, а сообщение может иметь много «получателей». Я пытался избежать огромных запросов или слишком большого количества моделей. Но, возможно, это неизбежно. Я думал, что все же спрошу. Вы никогда не знаете, когда кто-то может придумать решение ниндзя. смешной. Если бы это был вопрос HackerRank, я уверен, что кто-нибудь в нем разобрался бы.
Используйте сводную таблицу, это будет намного эффективнее, чем перебирать все сообщения, чтобы найти сообщения для получателя.