问题是一个集合被另一个集合过滤

时间:2019-12-12 13:50:53

标签: php mongodb

我有两个收藏夹:

用户:

{
  {"_id": 1, "orders": [1,2]},
  {"_id": 2, "orders": [3]},
  {"_id": 3, "orders": [4,5]}
}

订单:

{
  {"_id": 1, "paid": true},
  {"_id": 2, "paid": false},
  {"_id": 3, "paid": true},
  {"_id": 4, "paid": false},
  {"_id": 5, "paid": false}
}

如何在php中使用MongoDB \ Driver,从USERS集合中选择所有包含至少一个已付款订单的条目?目前,我将两个集合都包含在php中,使用数组比较时,只过滤用户集合。

此刻我的代码:

$users = _mongo_::collection('USERS')->find([]);
$paid_orders = _mongo_::collection('ORDERS')->find(['paid' => true]);
$paid_orders_ids = array_column($paid_orders, '_id');

$filtered_users = array_filter($users, function ($user) use ($paid_orders_ids) {
    return (boolean) array_intersect($user['orders'], $paid_orders_ids);
});

问题是,我是否可以仅通过一个MongoDB \ Driver查询立即获得过滤的用户列表?

1 个答案:

答案 0 :(得分:0)

您当前的代码根本不检查订单的付款状态。只是检查用户的订单之一是否在订单列表中(当然,它们全部都将存在)。相反,您想查看是否有任何用户的订单被标记为已付款。

为此,我们首先重新排列orders数组,以使id为索引,而付款状态为value。

$ordersManipulated = array();

foreach($paid_orders as $order)
{
    $ordersManipulated[$order["_id"]] = $order["paid"];
}

然后,我们更改array_filter()回调函数以检查与每个用户的每个订单相对应的订单行,并在找到当前用户的已付款订单时停止(因为我们只要求有一个已付款)订单)。

$filtered_users = array_filter($users, function ($user) use ($ordersManipulated) {
    foreach($user["orders"] as $order)
    {
        if($ordersManipulated[$order] === true)
        {
            return TRUE;
        }
    }
    return FALSE;
});

DEMO