>用戶提供了一個關鍵字或一些關鍵字要搜索。例如,搜索描述,關鍵字,類別,標籤等中包含“路由器”的產品的“路由器”。
>該站點將提供一些鏈接來微調搜索。例如,它可能會促使路由器有不同的品牌,並且價格範圍可能不同。
>用戶可以通過單擊提供的不同鏈接並最終獲得更自定義的結果集來進一步篩選結果。
>讓我們從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中文網其他相關文章!