matchory/data-pipe

数据处理管道框架

0.1.0 2021-09-23 14:42 UTC

This package is auto-updated.

Last update: 2024-09-23 21:24:19 UTC


README

一个用于在PHP中构建数据丰富管道的具有观点的框架

Data Pipe是一个用于在PHP中创建数据丰富管道的框架。此类应用程序通过获取一些信息,用附加数据丰富它,并通过对其应用转换来增强这些数据来工作。

作为一个更具体的例子,考虑一个客户管道:它获取客户的姓名,检索他们的购物历史年龄,然后通过从购物历史中删除旧项目并为客户分配目标组来增强记录。

当然,这仅仅描述了一些任意的业务逻辑,Data Pipe可以帮助你用一组可重用、可组合和封装的步骤来描述这个过程!

前言

请注意,此软件包仍在积极开发中,并且尚未准备好在生产环境中使用。我们仍在data-pipe之上构建自己的工作流程,因此一切都将根据1.0版本进行更改。如果您有兴趣塑造这个库的未来,我们非常欢迎您加入!

安装

使用composer将库作为依赖项安装

php composer require matchory/data-pipe

Symfony使用

此软件包包含一个Symfony集成。请阅读说明以开始使用。
集成将为您应用程序添加完全自动的管道配置。

Laravel使用

此软件包包含一个不完整的Laravel集成。请阅读说明以开始使用。

注意:我们尚未实现Laravel支持,因为我们目前不需要它。如果您有兴趣在Laravel应用程序中使用data-pipe,并且希望像使用Symfony一样自动配置管道,请打开一个问题

使用

注意:在开始使用Data Pipe之前,您应该熟悉其核心概念

Data Pipe通过设置具有预先配置的相互依赖节点的管道来工作。目前有两种类型的节点:收集器节点转换器节点(它们都是通用管道节点的变体)。
节点接收一个有效负载对象,修改并返回它。丰富节点添加新数据,后处理节点转换现有值。这种区别可能看起来无关紧要,但它允许大量的运行时优化。

创建节点

在其最简单的形式中,一个丰富节点可能看起来像这样

use Matchory\DataPipe\Nodes\AbstractCollector as Node;
use Matchory\DataPipe\PipelineContext;

class MyNode extends Node
{
    public function __construct(protected $yourInternalAgeApi) {}

    public function pipe(PipelineContext $context): PipelineContext
    {
        // Work with the data payload
        $email = $context->getPayload()->getAttribute('email');
        
        // Perform domain-specific work
        $age = $this->yourInternalAgeApi->query($email);
        
        // Update the payload
        if ($age) {
            $context->proposeChange($this, 'age', $age);
        }
        
        return $context;
    }
}

提出更改

请注意,您不能直接更新有效负载:每个节点都只接收实际有效负载的一个副本。相反,您可以提出对有效负载的更改。Data Pipe提供了一个简单的算法来应用最佳拟合更改。这允许为单个属性保留和比较多个值。

创建管道

现在我们有一个节点,让我们创建一个管道来将其添加进去

use Matchory\DataPipe\Payload\Payload;
use Matchory\DataPipe\Pipeline;
use Symfony\Component\EventDispatcher\EventDispatcher;

$nodes = [
    new MyNode(),
];
$eventDispatcher = new EventDispatcher();
$pipeline = new Pipeline($nodes, $eventDispatcher);

function(): Generator {
    yield new Payload([
        'email' => 'foo@bar.com'
    ]);
}

$pipeline->process(fetchNextPayload());

DI使用

这当然是一个虚构的例子;在现实中,依赖注入容器几乎会为你处理所有事情

use Matchory\DataPipe\Pipeline;

class EntryPoint {
    public function main(Pipeline $pipeline, Generator $recordFetcher): void
    {
        foreach ($recordFetcher as $record) {
            $pipeline->process($recordFetcher);
        }
    }
}

核心概念

Data Pipe使用几个构建块来构建你的管道。

管道节点

节点是构成管道的阶段。它们可以依赖于之前已执行的其他节点;这些依赖关系将在管道运行之前解决,因此您不需要手动定义顺序。管道处理的每个有效载荷都将被发送到管道中的所有节点,每个节点都有权对数据进行修改。
目前有两种类型的节点

收集器节点

增强记录以添加额外信息的节点称为收集器节点。这些节点可以可选地定义一个成本:它用于按成本对节点进行排序,并确定是否执行额外的节点是否必要。
想象你有两个数据源——你自己的内部数据库和一个按API调用收费的外部系统。数据库节点将比外部API的成本低。现在,如果我们正在寻找一些信息,我们将首先执行“较便宜”的节点(内部数据库),然后,只有在它不能满足我们的要求时,我们也会执行更昂贵的节点。

你拥有的节点越多,细粒度成本的优势就越明显:信息将始终以可能的最便宜方式获取。

转换器节点

转换器节点允许您细化、修改或比较之前收集的信息。这与数据丰富节点不同,因为它们通常在那些节点之后执行。

最佳匹配更改应用

你拥有的数据源越多,你将收集到的信息变体就越多。问题是确定这些变体中的最佳选项——例如,考虑一个电子邮件地址

根据一些规则,你可能会推断出与你要寻找的内容最接近的变体。现在,为了防止一系列节点相互覆盖结果,它们不是在有效载荷上设置属性,而是可以建议更改

$context->proposeChange($this, 'attribute_name', 42);

所有节点都可以提出对现有数据的修改,以及一个可选的置信度分数:例如,在电子邮件的例子中,我们可能会有一个垃圾邮件域的灰名单,并分配给该地址一个较低的置信度分数。这里的想法是,如果之后找不到更好的选择,就采用该电子邮件