1

プロファイルのチャット リストと最後のメッセージを時系列で表示するために、対応するユーザーとのメッセージを取得しようとしています。

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_id/$sender_id の組み合わせから最新のメッセージを取得しません。

したがって、最後のメッセージを持つユーザーのリストの代わりに、メッセージを持つユーザーのリストがあります。クエリの何が問題になっていますか? 手伝ってくれてありがとう!

方法 2 の結果

データベースに「chat_id」フィールドを作成しました。これは、基本的にrecipient_id + sender_idをアルファベット順に並べ替えたものです(user1がuser2にメッセージを送信するとuser1が送信者になり、後でuser2が応答すると彼が送信者になるため、並べ替えにより2人のユーザーが常に同じchat_id)。

クエリに DISTINCT を追加したよりも:

$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 DB

方法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.チャットのリストを取得している、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(Message .created)は確かに会話からの最新のメッセージを表示していますが、0=>Message 配列は別のメッセージ用です! ご覧$results[0]['Message']['created']の通り時と$results[0][0]['max_created']は違います!

4

1 に答える 1

2

ついに!作業ソリューション:

$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`'
);

上記のコードは、要件に従ってすべてのメッセージを取得します。あなたはできる

a) SINGLE QUERYに mysql JOIN を追加して、関連付けられたモデルを含めます (コードを単一クエリに整理します)

b) 2 つのクエリがよりスマートな方法で、メッセージの「ID」のみを選択し、ケーキの組み込み動作を含む別のクエリを作成します。ビヘイビアが適用されるので、これも良いかもしれません。

結果として配列ツリーが作成され、次のクエリで使用する実際の ID が次のように抽出されます。

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

c) ソリューションを CakePHP クエリ ビルダーに変換します... :) 挑戦してみませんか?

于 2015-09-20T20:38:45.753 に答える