首頁 > 後端開發 > php教程 > PINQ-查詢數據集 - 面式搜索

PINQ-查詢數據集 - 面式搜索

Lisa Kudrow
發布: 2025-02-20 12:29:14
原創
560 人瀏覽過

PINQ-查詢數據集 - 面式搜索

鑰匙要點

    PHP LINQ端口
  • pinq可以用MySQL模仿刻面搜索功能,提供強大而直接的方法。
  • >通過使用用戶提供的關鍵字來搜索產品,返回匹配的產品以及提供基於不同品牌,價格範圍和功能的搜索的鏈接來搜索產品。
  • > PINQ可以通過添加基本的搜索功能來擴展演示應用程序,例如在$範圍指定的步驟中按值分組。
  • >每次使用pinq檢索數據的刻面搜索都可以從MySQL Server檢索數據,可以通過使用緩存引擎來避免。 儘管是基本的演示,但Pinq的Facet搜索方法提供了足夠的改進空間,可以為更高級用例而建立。
  • 在第1部分中,我們簡要介紹了PHP LINQ端口的PinQ的安裝和基本語法。在本文中,我們將看到如何使用PINQ使用MySQL模仿刻面搜索功能。
  • >我們不會涵蓋本系列搜索的整個方面。有興趣的當事方可以參考網站和其他互聯網出版物上發表的相關文章。
  • >在網站上類似典型的搜索作品:>

>用戶提供了一個關鍵字或一些關鍵字要搜索。例如,搜索描述,關鍵字,類別,標籤等中包含“路由器”的產品的“路由器”。 >

該網站將返回與標準匹配的產品。

>該站點將提供一些鏈接來微調搜索。例如,它可能會促使路由器有不同的品牌,並且價格範圍可能不同。

>用戶可以通過單擊提供的不同鏈接並最終獲得更自定義的結果集來進一步篩選結果。
  • 式搜索是如此受歡迎和強大,您幾乎可以在每個電子商務網站中體驗它。
  • 不幸的是,刻面搜索不是MySQL提供的內置功能。如果我們使用mySQL,我們該怎麼辦,但也想為我們的用戶提供這樣的功能?
  • >使用Pinq,我們會看到一種同樣強大且直接的方法可以實現這一目標,就像我們在使用其他DB發動機時一樣 - 至少在某種程度上。
  • 延長第1部分演示
  • 注意:此部分中的所有代碼以及第1部分演示都可以在存儲庫中找到。
在本文中,我們將擴展第1部分中顯示的演示,並添加一些基本的搜索功能。

>讓我們從index.php開始,添加以下幾行:

>我們剛剛在演示應用程序中創建了另外兩個路由(使用Silex)。

>第一個途徑是將我們帶到頁面上,顯示與我們第一個搜索行為相匹配的所有記錄,即通過提供關鍵字來搜索。為了使演示簡單,我們從示例book_book表中選擇所有書籍。它還將顯示結果集和麵式的鏈接以進行進一步的導航。

>

>第二個路線將我們帶到另一個頁面,顯示了與上述步驟中產生的結果集中匹配進一步的架構搜索標準的記錄。它也將顯示刻面搜索鏈接。

在現實世界實現中,單擊一個刻面鏈接後,將調整結果頁面中的任何刻面過濾,以反映結果數據集的統計信息。通過執行此操作,用戶可以應用“附加”篩選,首先添加“品牌”,然後再添加“價格範圍”等。

>但是,在這個簡單的演示中,我們將跳過這種方法,所有刻度搜索和鏈接只會反映原始數據集的信息。這是我們演示中改進的第一個限制和第一個領域。

從上面的代碼中看到,實際函數位於另一個名為pinqdemo.php的文件中。讓我們查看提供相關的搜索功能的相關代碼。

facet類

首先,我們創建一個代表一個方面的類。通常,一個方面應該具有一些屬性:

    它在($ data)
  • 上運行的數據
  • ($ key)
  • >上的密鑰IT組
  • 鍵類型($ type)。它可以是以下之一:

    • >指定一個完整的字符串以進行確切的匹配
    • >指定字符串的部分(通常是開始),以使模式匹配>
    • >按值範圍
    • >指定值範圍
    如果密鑰類型為範圍,則需要指定一個值步,以確定範圍的上/下限;或者,如果密鑰類型是部分字符串,我們需要提供一個數字來指定要使用多少個字母來分組($ range)
  • >
  • 分組是一個方面中最關鍵的部分。方面可能返回的所有匯總信息取決於“分組”標準。通常,“完整字符串”,“部分字符串”和“值範圍”是最常用的。

在此類中,關鍵功能是根據數據和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()函數中,我們執行以下步驟:
  • >將原始數據轉換為可用於進一步處理的可PINQTRAVERAVERABLE對象。 >
  • 我們創建3個方面。 “作者”方面將分組在現場作者上,這是一個完整的字符串分組;字段標題和部分字符串分組的“標題”(首發6個字母計數);野外價格和範圍分組的“價格”(乘以10步)。
  • >最後,我們獲取方面並將其返回到test2函數,以便模板可以渲染數據和方面。
  • 顯示刻面和過濾的數據
>

>大多數時候,方面將顯示為鏈接,並將我們帶入過濾的數據集。

>我們已經創建了一個路由('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>
登入後複製
登入後複製
請注意我們如何構建鏈接的URI。我們同時使用了外循環的鍵(k)和內環密鑰(vv.key)作為路由('demo2/facet/{key}/{value}')的參數。鍵(vv.count)的計數用於修飾模板中的顯示(作為引導徽章)。

該模板將呈現如下所示:

(第一個顯示初始輸入頁面,第二個顯示了一個面積的結果,價格在$ 0到$ 10並由作者訂購) 好的,到目前為止,我們已經設法模仿了我們的Web應用程序中的一個面搜索功能! PINQ-查詢數據集 - 面式搜索
在我們結束本系列之前,我們將對此演示進行最終研究,看看可以做些改進的演示以及局限性是什麼。 PINQ-查詢數據集 - 面式搜索

改進要進行

總體而言,這是一個相當基本的演示。我們只是瀏覽了基本的語法和概念,並將它們偽造成一個可以進行的示例。正如我們之前看到的,可以改進一些區域,以使其更加靈活。

我們需要考慮提供“附加”標準搜索功能。我們當前的實現限制了僅在原始數據上應用於原始數據而不是篩選數據的架子搜索。這是我能想到的最重要的進步。

限制

>此處實施的刻面搜索具有根深蒂固的限制(對於其他方面的搜索實現可能是正確的):

我們每次都從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>
登入後複製
登入後複製
>當我們構造方面時,我們確實保存了在服務器端執行的一些SQL語句。我們只通過相同的查詢選擇查詢和3個不同的組,我們只是向Where語句發布一個選擇查詢,並使用PINQ提供聚合信息。

結論

在這一部分中,我們設法模仿了圖書收集站點的刻痕搜索能力。正如我所說,這僅僅是一個可以進行的演示,並且具有足夠的改進空間和一些默認限制。讓我們知道您是否在此示例上構建並可以向我們展示一些更高級的用例!

> PINQ的作者現在正在研究下一個主要版本版本(版本3)。我確實希望它能變得更強大。

隨時在下面留下您的評論和想法!

>

>常見問題(常見問題解答)有關PINQ和FACETED SEARCH

什麼是PINQ,與片段搜索有何關係?

PINQ是PHP庫,它提供了一種獨特,直觀且功能強大的查詢語言來操縱數組和其他數據集。它旨在簡化查詢和操縱數據的過程。關於刻面搜索,PINQ可用於創建可以根據多個標準過濾和排序數據的複雜查詢,這是FaceTed搜索的核心概念。

PINQ的架構搜索方法與其他方法有何不同?

pinq的FaceTed搜索方法是唯一的,因為它使用了基於PHP的查詢語言,該語言是一種廣泛使用的編程語言。這使得已經熟悉PHP的開發人員更容易實現式搜索。此外,PINQ的查詢語言設計為直觀且易於使用,可以簡化創建複雜查詢的過程。

>可以與其他數據庫一起使用PINQ,還是僅限於MySQL? > PINQ不限於MySQL。它可以與任何數據集一起使用,包括數組和其他數據庫。這種靈活性使PINQ成為需要使用不同類型數據的開發人員的多功能工具。

> PINQ如何處理大數據集?

PINQ旨在有效地處理大型數據集。它通過使用懶惰的評估策略來做到這一點,這意味著它僅在需要時才能處理數據。在使用大型數據集時,這可以顯著提高性能。

>使用PINQ進行片段搜索有什麼好處?首先,它簡化了創建複雜查詢的過程,從而可以節省開發人員的時間和精力。其次,它提供了一種強大而靈活的查詢語言,可以處理各種數據類型和結構。最後,它基於PHP,它是一種廣泛使用的編程語言,使開發人員更容易學習和使用。

PINQ適合初學者,還是更適合經驗豐富的開發人員? 🎜> PINQ設計為直觀且易於使用,使其適合初學者和經驗豐富的開發人員。但是,使用PINQ。查詢語言,可以根據多個標準準確過濾和排序數據。這使其可以提供精確且相關的搜索結果。

可以使用PINQ進行實時搜索嗎?

>

是的,PINQ可用於實時搜索。它有效地處理大型數據集及其創建複雜查詢的能力使其適合於實時搜索應用程序。

>

PINQ與其他php庫相比如何?由於其獨特,直觀且功能強大的查詢語言,從其他PHP庫中進行了搜索。它還可以從其可以處理的數據類型方面具有靈活性,並且其對大型數據集的有效處理使其成為開發人員的強大選擇。

>

是Pinq開源的,並且可以自定義嗎?是的,PINQ是一個開源庫,這意味著開發人員可以自定義以適應其特定需求。這種靈活性是使用PINQ進行片段搜索的另一個優點。

>

以上是PINQ-查詢數據集 - 面式搜索的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板