2015-09-17 43 views
0

我正在尝试与相应的用户获取消息,以便按时间顺序显示包含其最后一条消息的配置文件的聊天列表。CakePHP查找()组和按日期排序的复杂条件

array(
    0 => array(
     'Recepient' => array(
      'id' => ... 
      'name' => ... 
      ... 
     ), 
     'Message' => array(
      'content' => ... 
      'created' => ... 
      ... 
     ) 
    ), 
    1 => ... 
) 

,并以检索结果,我写这个find()方法:

$msgs = $this->Message->find('all', array(
    'group' => array('Recepient.id'), 
    'order'=>'Message.created DESC', 
    'conditions'=> 
     array(
      'OR'=> array(
       array('recepient_id'=>$pid), 
       array('sender_id' => $pid) 
      ) 
    ) 
)); 

我有什么:

  • 消息相对应的 “Recepient”,
  • 按时间顺序

问题:

  • 该查询不检索来自$ recepient_id/$ sender_id组合的最新消息。

因此,不是具有最后一条消息的用户列表,我有一个带有消息的用户列表。我的查询有什么问题?感谢帮助!

方法2个结果

我创建了一个基本上是数据库“chat_id”字段recepient_id + SENDER_ID字母顺序排序(因为如果用户1发送用户2的消息user1的发送者,后来当user2的回应,他成为发件人,所以排序将确保两个用户将始终具有相同的chat_id)。

比我还清晰地向查询:

$this->Message->recursive = 0; $msgs = $this->Message->find('all', array( 'fields' => array('DISTINCT Message.chat_id','Message.*','Recepient.*'), 'order'=>'Message.created DESC', 'conditions'=> array( 'OR'=> array( array('recepient_id'=>$pid), array('sender_id' => $pid) ) ) ));

,它不工作!我现在正在为同一个对话收到多封邮件。

如果我从查询中删除消息字段和收件人字段,我会得到正确数量的“聊天”。 'fields' => array('DISTINCT Message.chat_id'), 但这不是解决方案。

的CakePHP版本2.7.0 MySQL数据库

方法3个结果

$msgs = $this->Message->find('all', array( 'order'=>'Message.created DESC', 'fields' => 'recepient_id, content, max(Message.created) as max_created', 'group'=>'recepient_id', // 'contain' => array('Recepient'), 'conditions'=>array('chat_id' => $chats) ));

我放弃了在单找到方法来解决这个问题,所以现在1.I我得到的聊天列表2.我想从每次聊天中找到最后一条消息。 根据http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/我发现的查询应该可以工作。什么情况是

(int) 0 => array(
     'Message' => array(
      'recepient_id' => '55e6d764-1444-4aad-a909-9042f07f76da', 
      'content' => '1st msg', 
      'created' => '2015-09-20 18:24:17', 
      'created_nice' => '2 hours ago' 
     ), 
     (int) 0 => array(
      'max_created' => '2015-09-20 18:24:28' 
     ) 
    ), 

领域max(消息.创建)确实展示了最新的消息,从谈话但是0 =>信息排列是不同的消息!正如你所见,$results[0]['Message']['created']时间和$results[0][0]['max_created']是不同的!

+0

'消息'有很多'收件人'吗?你有没有检查过Cake发现的这个查询的SQL查询?我怀疑这个查询不是你所期望的! – drmonkeyninja

+1

您使用的是CakePHP的哪个版本? –

+0

听起来像'distinct'是一个你应该看看的术语......在[书]中有'distinct'的外观(http://book.cakephp.org/2.0/en/models/retrieving-your -data.html)... –

回答

0

终于!工作解决方案:

$db = $this->Message->getDataSource(); 
$chats = $db->fetchAll(
    'select id from (select * from messages order by created desc) Message 
    where recepient_id = "'.$pid.'" or sender_id = "'.$pid.'" 
    group by `chat_id`' 
); 

上面的代码将检索所有消息,遵循要求。您可以

一)单个查询添加MySQL JOIN包括关联的模型(我们保持代码的单一查询整齐)

B)两个查询,但更聪明更简单的方法,只选择“IDS”的消息,并创建另一个查询,将蛋糕的建立在可容纳的行为。这可能会更好,因为行为将被应用。

您将有树阵,结果挖出了一个查询的实际使用IDS如下:

$chats = Set::extract("/Message/id",$chats);

C)翻译解决方案,CakePHP的查询生成器... :)弥补一个挑战?