我有下面的 foreach 循环,它迭代用户可以应用的一堆不同的自定义规则。
public function parse(Document $document)
{
$content = $document->text;
$rules = $document->stream->fieldrules;
foreach ($rules as $rule) {
$class = $this->getClass($rule);
$content = $class->apply($content);
//Save to database.
$fieldresult = new FieldRuleResult();
$fieldresult->create([
'field_rule_id' => $rule->field_id,
'document_id' => $document->id,
'content' => $content
]);
}
}
如您所见,我在每次迭代时调用数据库。某些用户可能定义了最多 50 条规则,这将导致 50 条插入查询。所以我相信我可能遇到了 n+1
问题。
我想知道 - 这里的最佳实践是什么?我尝试搜索 Laravel 文档,并找到了 createMany 方法。所以我尝试将迭代重构为以下内容:
$result = [];
foreach($rules as $rule)
{
$class = $this->getClass($rule);
$content = $class->apply($content);
$fieldresult = new FieldRuleResult();
$result[] = [
'field_rule_id' => $rule->field_id,
'document_id' => $document->id,
'content' => $content];
}
return $rules->createMany($result);
这给了我以下错误:
Method Illuminate\Database\Eloquent\Collection::createMany does not exist.
现在我想这是因为 $rules
返回一个集合。我尝试将其更改为:
return $document->stream->fieldrules()->createMany($result);
这给了我以下错误:
Call to undefined method Illuminate\Database\Eloquent\Relations\HasManyThrough::createMany()
最佳答案
Illuminate/Database/Query/Builder
中有一个名为 insert
的方法可用。此方法允许您在一个查询中插入多个模型。请注意,这不会像所有多合一查询方法那样触发 Eloquent 事件。
就像您已经完成的那样,将数据存储在数组中并在循环完成后执行查询。不过这次您可以使用insert
。
$content = 'your content here...';
$data = [];
foreach($rules as $rule) {
$class = $this->getClass($rule);
$content = $class->apply($content);
$data[] = [
// ...
'content' => $content
];
}
FieldRuleResult::insert($data);
不能 100% 确定这直接适用于模型。然而在 documentation您可以找到一个带有 DB
外观的示例。
关于PHP - 在 foreach 循环之外保存到数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55364555/