我想从 MongoDB 集合中检索一些数据,该集合包含 1M 个文档,并且每天都在增加。
出于某些特定目的,我需要立即获取一些数据。但是,我获取的数据大小可能很小。然而,就像一次 25-30K 文档一样,我需要获取给定日期范围的数据。
我尝试了几种方法,我尝试过的最接近DB的方法是
return $collection->aggregate([
[
'$match' => [
'created_at' => [
'$gte' => $from->format('Y-m-d H:i:s'),
'$lte' => $to->format('Y-m-d H:i:s'),
],
],
],
[
'$project' => [
'user_id' => 1,
'created_at' => 1,
'checked_out_at' => 1,
'department.name' => 1,
'department.address' => 1,
'_id' => 0,
],
],
[
'$sort' => [
'user_id' => 1,
'created_at' => 1,
],
],
]);
});
我收到了带有这些代码的小型收藏的回复,但没有收到大型收藏的回复。
我已经用 MongoDB 罗盘尝试了这些(如下图),这些过滤器也在 350 毫秒内从大型数据库中为我提供了数据。但为什么我在 Laravel 中使用它时它不起作用?
感谢您抽出宝贵的时间。
我已经解决了这些问题。 MongoDB 可以更快地处理查询。因此,我必须完成数据库内的所有处理,并仅提取我的目的所需的文档。
这样,即使MongoDB在1s-2s内处理完所需的数据,我也不会面临内存限制而不是时间限制。
这是我修改后的代码。
return $collection->aggregate([
[
'$match' => [
'created_at' => [
'$gte' => Carbon::parse($this->range[0])->startOfDay()->toDateTimeString(),
'$lte' => Carbon::parse($this->range[1])->addDay()->startOfDay()->toDateTimeString(),
],
],
],
[
'$group' => [
'_id' => [
'user_id' => '$user_id',
'date' => ['$dateToString' => ['format' => '%Y-%m-%d', 'date' => ['$toDate' => '$created_at']]],
],
'employee_code' => ['$max' => '$user.code'],
'name' => ['$max' => '$user.name'],
'checkin_outlet' => ['$first' => '$department.name'],
'first_check_in' => ['$min' => '$created_at'],
'first_checkin_address' => ['$first' => '$department.address'],
'checkout_outlet' => ['$last' => '$department.name'],
'last_check_out' => ['$max' => '$checked_out_at'],
'last_checkout_address' => ['$last' => '$department.address'],
],
],
[
'$project' => [
'_id' => 0,
'user_id' => '$_id.user_id',
'employee_code' => 1,
'name' => 1,
'date' => '$_id.date',
'checkin_outlet' => 1,
'first_check_in' => 1,
'first_checkin_address' => 1,
'checkout_outlet' => 1,
'last_checkout_address' => 1,
'last_check_out' => 1,
],
],
[
'$sort' => ['date' => 1,'user_id'=> 1],
],
]);
});