我有这样的查询,应该获取包含其发件人信息及其收件人列表的邮件列表(考虑 groupID 和 senderID 函数参数):
(for {
groupUsers <- Users.users if targets.groupID === groupID
mRecipients <- recipients if mRecipients.targetID === groupUsers.id
message <- messages if message.senderID === groupUsers.id || message.id === mRecipients.messageID
sender <- Users.users if sender.id === m.senderID
} yield (message, sender ,mRecipients)).list.map{ result => new FullMessage(result ._1, result ._2, result ._3) }
但是当我想要一个元组(消息,用户,列表[收件人])时,我得到了一个(消息,用户,收件人)的元组。 。我如何设法得到这样的结果?
谢谢大家。
答案 0 :(得分:1)
嗯......代码将根据您编写的内容生成输出,而不是根据您的需要生成输出。专注于这一部分......
yield (message, sender ,mRecipients)
您正在产生(message, sender, mRecipents)
你在理解中做到了这一点
mRecipients <- recipients if mRecipients.targetID === targetID
message <- messages if message.senderID === senderID || message.id === mRecipients.messageID
sender <- Users.users if sender.id === m.senderID
此处每个表达式recipients if mRecipients.targetID === targetID
都评估为Query
monad。
要理解这是错误的,它与下面的内容非常相似,让我们想一想当我们这样做时会发生什么,
scala>:pa
// Entering paste mode (ctrl-D to finish
for{
i <- List( 1, 2, 3 )
j <- List( 1, 2, 3 )
k <- List( 1, 2, 3 )
} yield( i, j, k )
// Exiting paste mode, now interpreting.
res1: List[(Int, Int, Int)] = List((1,1,1), (1,1,2), (1,1,3), (1,2,1),
(1,2,2), (1,2,3), (1,3,1), (1,3,2), (1,3,3), (2,1,1), (2,1,2), (2,1,3),
(2,2,1), (2,2,2), (2,2,3), (2,3,1), (2,3,2), (2,3,3), (3,1,1), (3,1,2),
(3,1,3), (3,2,1), (3,2,2), (3,2,3), (3,3,1), (3,3,2), (3,3,3))
简单来说,for comprehensions
执行类似于解开monad
并获取其中值的迭代器的内容...然后它再次将生成的值包装到monad
中
所以,如果你这样做,
scala>:pa
// Entering paste mode (ctrl-D to finish
for{
l <- Some( List( 1, 2, 3 ) )
i <- Some( 1 )
} yield ( l, i )
// Exiting paste mode, now interpreting.
res1: Option[(List[Int], Int)] = Some((List(1, 2, 3),1))
另外......您的数据模型有点不对劲。
什么是recipients
?告诉我,我可能会以更好,更有效的方式解决您的问题。
但考虑到我对你的数据模型的猜测,现在如果你想要正确的收件人列表,你将不得不做类似的事情,
// List[ ( Message, List[ Recipients] ) ]
val messageAndRecipentsList = ( for {
// First get all possible recipents
possibleRecipient <- recipients if possibleRecipient.targetID === targetID
// Now get all relevant messages for sender and possibleRecipeint
message <- messages if message.senderID === senderID || message.id === possibleRecipient.messageID
// Now get list of recipents for each of these messages
messageRecipients <- for {
messageRecipient <- recipients if messageRecipient.messageID === message.id
} yield ( messageRecipient ).list
} yield ( message, messageRecipients ) ).list
// Now lets add sender for each of these messages, I am guessing sender
// should be exactly one for each sendorId. So... instead of querying for
// same user for every message lets just query it once and add to every
// tuple of the above list,
val sender = ( for {
sender <- Users.users if sender.id === senderID
} yield sender ).list.head
val finalList = messageAndRecipentsList.map ( {
case ( message, msaageRecipents ) => new FullMessage( message, sender, messageRecipients )
} )