>用户提供了一个关键字或一些关键字要搜索。例如,搜索描述,关键字,类别,标签等中包含“路由器”的产品的“路由器”。
>该站点将提供一些链接来微调搜索。例如,它可能会促使路由器有不同的品牌,并且价格范围可能不同。
>用户可以通过单击提供的不同链接并最终获得更自定义的结果集来进一步筛选结果。
>让我们从index.php开始,添加以下几行:
>我们刚刚在演示应用程序中创建了另外两个路由(使用Silex)。
>第一个途径是将我们带到页面上,显示与我们第一个搜索行为相匹配的所有记录,即通过提供关键字来搜索。为了使演示简单,我们从示例book_book表中选择所有书籍。它还将显示结果集和面式的链接以进行进一步的导航。
>>第二个路线将我们带到另一个页面,显示了与上述步骤中产生的结果集中匹配进一步的架构搜索标准的记录。它也将显示刻面搜索链接。
在现实世界实现中,单击一个刻面链接后,将调整结果页面中的任何刻面过滤,以反映结果数据集的统计信息。通过执行此操作,用户可以应用“附加”筛选,首先添加“品牌”,然后再添加“价格范围”等。>但是,在这个简单的演示中,我们将跳过这种方法,所有刻度搜索和链接只会反映原始数据集的信息。这是我们演示中改进的第一个限制和第一个领域。
从上面的代码中看到,实际函数位于另一个名为pinqdemo.php的文件中。让我们查看提供相关的搜索功能的相关代码。
facet类
在此类中,关键功能是根据数据和facet密钥属性返回刻面结果集。我们注意到,对于不同类型的密钥,有不同的方法来分组数据。在上面,我们已经显示了代码在按$范围指定的步骤中按值范围进行分组的代码的样子。
<span>$app->get('demo2', function () use ($app) </span><span>{ </span> <span>global $demo; </span> <span>$test2 = new pinqDemo<span>\Demo</span>($app); </span> <span>return $test2->test2($app, $demo->test1($app)); </span><span>} </span><span>); </span> <span>$app->get('demo2/facet/{key}/{value}', function ($key, $value) use ($app) </span><span>{ </span> <span>global $demo; </span> <span>$test3 = new pinqDemo<span>\Demo</span>($app); </span> <span>return $test3->test3($app, $demo->test1($app), $key, $value); </span><span>} </span><span>);</span>
>
在getfacet()函数中,我们执行以下步骤:>我们已经创建了一个路由('demo2/facet/{key}/{value}'),以显示刻面搜索结果和facet链接。
>路由采用两个参数,反映了我们固定的密钥和该密钥的值。最终从该路线调用的test3函数在下面摘录:
>基本上,根据密钥,我们应用了与传递的值相对应并获取进一步筛选数据的过滤(where子句中的匿名函数)。我们还可以指定刻面数据的顺序。
<span>$app->get('demo2', function () use ($app) </span><span>{ </span> <span>global $demo; </span> <span>$test2 = new pinqDemo<span>\Demo</span>($app); </span> <span>return $test2->test2($app, $demo->test1($app)); </span><span>} </span><span>); </span> <span>$app->get('demo2/facet/{key}/{value}', function ($key, $value) use ($app) </span><span>{ </span> <span>global $demo; </span> <span>$test3 = new pinqDemo<span>\Demo</span>($app); </span> <span>return $test3->test3($app, $demo->test1($app), $key, $value); </span><span>} </span><span>);</span>
>最后,我们在模板中显示数据(以及方面)。此路由呈现与路由“ demo2”使用的模板相同的模板)。
> 接下来,让我们看一下模板,看看如何显示facet链接。我正在使用bootstrap,因此这里使用的CSS组件应该很熟悉:>我们必须记住,应用程序生成的面是一个嵌套数组。在第一层中,它是所有方面的数组,在我们的情况下,我们总共有3个(分别用于作者,标题,作者)。
对于每个方面,它是一个“键值”配对阵列,因此我们可以以传统的方式迭代。
<span>namespace classFacet </span><span>{ </span> <span>use Pinq<span>\ITraversable</span>, </span> Pinq\Traversable<span>; </span> <span>class Facet </span> <span>{ </span> <span>public $data; // Original data </span> <span>public $key; // the field to be grouped on </span> <span>public $type; // F: full string; S: start of a string; R: range; </span> <span>public $range; // Only valid if $type is not F </span> <span>... </span> <span>public function getFacet() </span> <span>{ </span> <span>$filter = ''; </span> <span>if ($this->type == 'F') // Full string </span> <span>{ </span> <span>... </span> <span>} </span> <span>elseif ($this->type == "S") //Start of string </span> <span>{ </span> <span>... </span> <span>} </span> <span>elseif ($this->type == "R") // A value range </span> <span>{ </span> <span>$filter = $this->data </span> <span>->groupBy(function($row) </span> <span>{ </span> <span>return floor($row[$this->key] / $this->range) * $this->range; </span> <span>}) </span> <span>->select(function (ITraversable $data) </span> <span>{ </span> <span>return ['key' => $data->last()[$this->key], 'count' => $data->count()]; </span> <span>}); </span> <span>} </span> <span>return $filter; </span> <span>} </span> <span>} </span><span>}</span>
该模板将呈现如下所示:
(第一个显示初始输入页面,第二个显示了一个面积的结果,价格在$ 0到$ 10并由作者订购)
好的,到目前为止,我们已经设法模仿了我们的Web应用程序中的一个面搜索功能!
在我们结束本系列之前,我们将对此演示进行最终研究,看看可以做些改进的演示以及局限性是什么。
我们需要考虑提供“附加”标准搜索功能。我们当前的实现限制了仅在原始数据上应用于原始数据而不是筛选数据的架子搜索。这是我能想到的最重要的进步。
限制
我们每次都从MySQL Server检索数据。
>
此应用使用Silex作为框架。对于任何单一入口框架,例如Silex,Symfony,Laravel,每次要分析路由时,都会调用其index.php(或app.php),并将调用控制器的功能。在我们的index.php中查看代码,我们将看到这也意味着以下代码行:
>每次显示应用程序中的一个页面时,都会被调用,这意味着每次都执行以下行:
><span>$app->get('demo2', function () use ($app) </span><span>{ </span> <span>global $demo; </span> <span>$test2 = new pinqDemo<span>\Demo</span>($app); </span> <span>return $test2->test2($app, $demo->test1($app)); </span><span>} </span><span>); </span> <span>$app->get('demo2/facet/{key}/{value}', function ($key, $value) use ($app) </span><span>{ </span> <span>global $demo; </span> <span>$test3 = new pinqDemo<span>\Demo</span>($app); </span> <span>return $test3->test3($app, $demo->test1($app), $key, $value); </span><span>} </span><span>);</span>
>如果我们避免使用框架会更好吗?好吧,除了在没有框架的情况下开发应用程序并不是一个好主意,我们仍然面临同样的问题:数据(和状态)并不是一个HTTP呼叫对另一个http呼叫的持续性。这是HTTP的基本特征。使用缓存引擎应该避免这种情况。
<span>namespace classFacet </span><span>{ </span> <span>use Pinq<span>\ITraversable</span>, </span> Pinq\Traversable<span>; </span> <span>class Facet </span> <span>{ </span> <span>public $data; // Original data </span> <span>public $key; // the field to be grouped on </span> <span>public $type; // F: full string; S: start of a string; R: range; </span> <span>public $range; // Only valid if $type is not F </span> <span>... </span> <span>public function getFacet() </span> <span>{ </span> <span>$filter = ''; </span> <span>if ($this->type == 'F') // Full string </span> <span>{ </span> <span>... </span> <span>} </span> <span>elseif ($this->type == "S") //Start of string </span> <span>{ </span> <span>... </span> <span>} </span> <span>elseif ($this->type == "R") // A value range </span> <span>{ </span> <span>$filter = $this->data </span> <span>->groupBy(function($row) </span> <span>{ </span> <span>return floor($row[$this->key] / $this->range) * $this->range; </span> <span>}) </span> <span>->select(function (ITraversable $data) </span> <span>{ </span> <span>return ['key' => $data->last()[$this->key], 'count' => $data->count()]; </span> <span>}); </span> <span>} </span> <span>return $filter; </span> <span>} </span> <span>} </span><span>}</span>
结论
在这一部分中,我们设法模仿了图书收集站点的刻痕搜索能力。正如我所说,这仅仅是一个可以进行的演示,并且具有足够的改进空间和一些默认限制。让我们知道您是否在此示例上构建并可以向我们展示一些更高级的用例!
随时在下面留下您的评论和想法!
>>常见问题(常见问题解答)有关PINQ和FACETED SEARCH
什么是PINQ,与片段搜索有何关系?
>
PINQ与其他php库相比如何?由于其独特,直观且功能强大的查询语言,从其他PHP库中进行了搜索。它还可以从其可以处理的数据类型方面具有灵活性,并且其对大型数据集的有效处理使其成为开发人员的强大选择。>
以上是PINQ-查询数据集 - 面式搜索的详细内容。更多信息请关注PHP中文网其他相关文章!