我在和鲁门和mongodb合作
我希望根据文件夹获取(总未读)和总消息计数。
我的mongodb查询如下,
$totalEmails = DB::connection('mongodb')
->select("sum(if(is_read==0,1,0)) as unread", "count(message_id) as total", "folder_id")
->collection('email_message')
->where('email_account_id', (int)$request->email_account_id)
->where('status', "Active")
->groupBy("folder_id")
->get();它给了我以下的错误,
FatalErrorException in Connection.php line 333:
Call to a member function prepare() on null请帮我解决这个issue.thank你。
我已经通过更改查询来解决该错误,如下所示,
$totalEmails = DB::connection('mongodb')
->collection('email_message')
->select("sum(if(is_read==0,1,0)) as unread", "count(message_id) as total", "folder_id")
->where('email_account_id', (int)$request->email_account_id)
->where('status', "Active")
->groupBy("folder_id")
->get();但这并没有给我预期的结果,
它给我的结果如下,
[_id] => Array
(
[folder_id] => 5bee461e19f043020c001844
)
[folder_id] => 5bee461e19f043020c001844
[sum(if(is_read==0,1,0)) as unread] =>
[count(message_id) as total] => 但我的期望是
[_id] => Array
(
[folder_id] => 5bee461e19f043020c001844
)
[folder_id] => 5bee461e19f043020c001844
[unread] => 2
[total] => 10你能告诉我查询哪里不对吗?
如果我使用下面的查询
$totalEmails = DB::connection('mongodb')
->selectRaw("sum(if(is_read==0,1,0)) as unread", "count(message_id) as total", "folder_id")
->collection('email_message')
->where('email_account_id', (int)$request->email_account_id)
->where('status', "Active")
->groupBy("folder_id")
->get();它给了我一个错误,
ErrorException in Builder.php line 245:
Argument 2 passed to Illuminate\Database\Query\Builder::selectRaw() must be of the type array, string given,如果我使用下面的查询,
$totalEmails = DB::connection('mongodb')
->collection('email_message')
->selectRaw("sum(if(is_read==0,1,0)) as unread,count(message_id) as total,folder_id")
->where('email_account_id', (int)$request->email_account_id)
->where('status', "Active")
->groupBy("folder_id")
->get();它给我的结果是,
[_id] => Array
(
[folder_id] => 5bee461e19f043020c001844
)
[folder_id] => 5bee461e19f043020c001844
[sum(if(is_read==0,1,0)) as unread,count(message_id) as total,folder_id] => 请帮我得到我的预期结果
发布于 2018-11-16 11:09:32
据我所知,这是一个非常复杂的查询,而且很难用laravel方法生成,因此我建议使用$aggregate进行原始查询,如下面的示例所示:
$totalEmails = DB::connection("mongodb")
->collection("email_message")
->raw(function ($collection) {
return $collection->aggregate(
[
[
"\$match" => [
"email_account_id" => (int)$request->email_account_id,
"status" => "active"
]
],
[
"\$group" => [
"_id" => [
"folder_id" => "\$folder_id"
],
"unread" => [
"\$sum" => [
"\$switch" => [
"branches" => [
["case" => [
"\$eq" => [
"\$is_read", '0,1,0'
]
],
"then" => 1
]
],
"default" => 0
]
]
],
"total" => [
"\$sum" => 1
]
]
]
]
);
});
$collectedResult = array();
foreach ($result as $k => $v) {
$collectResult[] = $v->jsonSerialize();
}
return $collectedResult;我已经格式化了它,使其尽可能可读,并且我将尽可能地解释查询的每个部分,这样您就知道它做了什么。
通过使用raw语句,我们可以使用模拟mongo $aggregate的aggregate()函数。
首先,我们希望在email_account_id上进行筛选,这是使用$match方法完成的,请注意,$是转义的,因为否则php会将其解释为变量。
在此之后,我们需要执行使用此部分完成的组:
"_id" => [
"folder_id" => "\$folder_id"
]这将创建带有键_id的数组的folder_id列,并将DB列'folder_id‘的所有唯一值收集到值中。
因此,这个部分将生成一个具有唯一folder_ids的元素数组,然后必须为这些文件夹计算未读和总消息。
总数很简单,是用$sum操作符完成的。未读部分稍微复杂一些,因为这需要在is_read操作符上进行筛选。这是通过一个switch语句和默认值0完成的(条件失败时不要计算)。
原始查询将返回一个MongoCursor,所以最后一部分是收集这些结果。
我希望这对你有帮助,如果有什么不清楚的地方,请告诉我。
发布于 2018-11-16 05:26:52
我不确定这是否是导致您的问题的原因,但是您的代码中有一个错误。
它应该是:
$totalEmails = DB::connection('mongodb')
->selectRaw("sum(if(is_read==0,1,0)) as unread, count(message_id) as total, folder_id")
->collection('email_message')
->where('email_account_id', (int)$request->email_account_id)
->where('status', "Active")
->groupBy("folder_id")
->get();selectRaw需要在select中包含原始代码。这是获得更多信息的文档
https://stackoverflow.com/questions/53331812
复制相似问题