You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在REST API中返回数据表中唯一对话对的JSON结果

解决重复对话对的问题

看起来你是想从聊天消息表中获取与指定用户有过对话的所有唯一用户对,而不是每条消息都返回。当前的查询会返回所有包含目标UserID的消息记录,这就导致了(17,18)和(18,17)这类同对话的重复出现。下面给你两种解决方案,优先推荐数据库层面处理,效率更高。

方案1:数据库层面去重(推荐)

我们可以利用MySQL的LEAST()和GREATEST()函数,把对话双方的ID按固定顺序排列,再结合DISTINCT关键字获取唯一的对话对。这样不管消息是A发给B还是B发给A,都会被视为同一个对话,只返回一次。

同时,必须修复你代码中的SQL注入风险——直接把$_GET['UserID']拼进SQL是非常危险的,一定要用预处理语句绑定参数。

修改后的完整PHP代码:

<?php
class ConnectionInfo {
    public $conn;
    public function GetConnection() {
        $this->conn = mysqli_connect("serv", "user","pass", "db") or die(mysqli_error($this->conn));
    }
}

$connectionInfo = new ConnectionInfo();
$connectionInfo->GetConnection();

if (!$connectionInfo->conn) {
    echo 'No Connection';
} else {
    $UserID = $_GET['UserID'];
    // 用预处理语句+去重逻辑构建查询
    $query = "SELECT DISTINCT
                LEAST(SenderID, RecieverID) AS FirstID,
                GREATEST(SenderID, RecieverID) AS SecondID
              FROM MyTable
              WHERE SenderID = ? OR RecieverID = ?";
    
    $stmt = mysqli_prepare($connectionInfo->conn, $query);
    mysqli_stmt_bind_param($stmt, "ss", $UserID, $UserID);
    mysqli_stmt_execute($stmt);
    $result = mysqli_stmt_get_result($stmt);
    
    if (!$result) {
        echo 'Query failed';
    } else {
        $contacts = array();
        while ($row = mysqli_fetch_array($result)) {
            // 如果你希望把请求的UserID始终放在SenderID位置,可以加个判断
            $contact = ($row['FirstID'] == $UserID) ? 
                array("SenderID" => $row['FirstID'], "RecieverID" => $row['SecondID']) :
                array("SenderID" => $row['SecondID'], "RecieverID" => $row['FirstID']);
            
            array_push($contacts, $contact);
        }
        echo json_encode(array('results' => $contacts), JSON_PRETTY_PRINT);
    }
    // 清理资源
    mysqli_stmt_close($stmt);
    mysqli_close($connectionInfo->conn);
}
?>

这段代码会返回每个唯一对话对,且可以选择把请求的UserID固定在SenderID位置,完全符合你期望的输出格式。

方案2:PHP代码层面去重

如果暂时无法修改SQL,也可以在代码中过滤重复的对话对。思路是给每个对话对生成一个唯一标识(比如把两个ID按从小到大排序后拼接),用这个标识来判断是否已经处理过该对话。

修改你的循环逻辑即可:

$contacts = array();
$seenConversations = []; // 记录已处理的对话对

while ($row = mysqli_fetch_array($stmt)) {
    // 生成唯一对话标识
    $minId = min($row['SenderID'], $row['RecieverID']);
    $maxId = max($row['SenderID'], $row['RecieverID']);
    $conversationKey = "$minId-$maxId";
    
    if (!isset($seenConversations[$conversationKey])) {
        $seenConversations[$conversationKey] = true;
        $contact = array(
            "SenderID" => $row['SenderID'],
            "RecieverID" => $row['RecieverID']
        );
        array_push($contacts, $contact);
    }
}

不过这种方法在数据量大时会占用更多内存,所以还是优先推荐数据库层面的解决方案。

内容的提问来源于stack exchange,提问作者Carlos Rodrigez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:35:25