Kami tidak akan merangkumi aspek penuh carian faceted dalam siri ini. Pihak yang berminat boleh merujuk kepada artikel yang berkaitan yang diterbitkan di SitePoint dan penerbitan Internet yang lain.
Carian facet yang biasa berfungsi seperti ini dalam laman web:
Pengguna menyediakan kata kunci atau beberapa kata kunci untuk dicari. Sebagai contoh, "penghala" untuk mencari produk yang mengandungi "penghala" dalam keterangan, kata kunci, kategori, tag, dan lain -lain
Malangnya, carian faceted bukan ciri terbina dalam yang disediakan oleh MySQL lagi. Apa yang boleh kita lakukan jika kita menggunakan MySQL tetapi juga ingin menyediakan pengguna kami dengan ciri sedemikian?
Dengan Pinq, kita akan melihat ada pendekatan yang sama kuat dan mudah untuk mencapai ini seperti ketika kita menggunakan enjin DB yang lain - sekurang -kurangnya dengan cara.Memperluas Bahagian 1 Demo
Nota: Semua kod di bahagian ini dan demo Bahagian 1 boleh didapati di repo.
mari kita mulakan dengan index.php dengan menambahkan beberapa baris berikut:
kami hanya mencipta dua lagi laluan dalam aplikasi demo kami (menggunakan Silex).
Laluan pertama adalah untuk membawa kami ke halaman yang menunjukkan semua rekod yang sepadan dengan tingkah laku carian pertama kami, iaitu, cari dengan memberikan kata kunci. Untuk memastikan demo mudah, kami memilih semua buku dari jadual Book_Book Sample. Ia juga akan memaparkan set keputusan dan pautan yang diperolehi untuk navigasi selanjutnya.
Laluan kedua membawa kami ke halaman lain yang menunjukkan rekod yang sepadan dengan kriteria carian facet selanjutnya dalam set hasil yang dihasilkan dalam langkah di atas. Ia akan memaparkan pautan carian yang diperoleh juga.
Dalam pelaksanaan dunia sebenar, selepas pautan faceted diklik, mana -mana penapisan faceted di halaman hasil akan diselaraskan untuk mencerminkan maklumat statistik set data hasil. Dengan melakukan ini, pengguna boleh memohon pemeriksaan "add-on", menambah "jenama" pertama kemudian "julat harga", dan lain-lain
Ini adalah sekatan pertama dan kawasan pertama untuk penambahbaikan dalam demo kami.
Seperti yang kita lihat dari kod di atas, fungsi sebenar berada dalam fail lain yang dipanggil pinqdemo.php. Mari lihat kod yang relevan yang menyediakan ciri carian faceted.
Pertama, kami membuat kelas untuk mewakili aspek. Umumnya, aspek harus mempunyai beberapa sifat:
<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>
Membuat aspek dan memaparkan data asal
<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>
Kebanyakan masa, aspek akan dipaparkan sebagai pautan dan membawa kami ke set data yang ditapis.
Kami telah membuat laluan ('Demo2/Facet/{Key}/{Value}') untuk memaparkan hasil carian yang diperolehi dan pautan facet.
Laluan mengambil dua parameter, mencerminkan kunci yang kita lakukan dan nilai kunci itu. Fungsi Test3 yang akhirnya dipanggil dari laluan itu dikutip di bawah:
<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>
Pada dasarnya, bergantung kepada kunci, kami memohon penapisan (fungsi tanpa nama di mana klausa) sepadan dengan nilai yang diluluskan dan dapatkan data yang ditayangkan selanjutnya. Kami juga boleh menentukan susunan data yang diperolehi.
Akhirnya, kami memaparkan data (bersama -sama dengan aspek) dalam templat. Laluan ini menjadikan templat yang sama seperti yang digunakan oleh laluan 'Demo2').
Seterusnya, mari kita lihat templat dan lihat bagaimana pautan aspek dipaparkan. Saya menggunakan bootstrap jadi komponen CSS yang digunakan di sini harus cukup akrab:
<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>
kita harus ingat bahawa aspek yang dihasilkan oleh aplikasi kami adalah array bersarang. Dalam lapisan pertama, ia adalah pelbagai aspek, dan dalam kes kita, kita mempunyai sejumlah 3 (untuk pengarang, tajuk, pengarang, masing -masing).
Bagi setiap aspek, ia adalah "nilai utama" yang dipasangkan supaya kita dapat berulang dengan cara tradisional.
Sila ambil perhatian bagaimana kita membina URI pautan. Kami menggunakan kedua -dua kunci gelung luar (k) dan kunci gelung dalaman (vv.key) untuk menjadi parameter dalam laluan ('demo2/facet/{key}/{value}'). Kiraan kunci (vv.count) digunakan untuk menyentuh paparan dalam templat (sebagai lencana bootstrap).
Templat akan diberikan seperti yang ditunjukkan di bawah:
Baiklah, setakat ini kami berjaya meniru ciri carian yang diperolehi dalam aplikasi web kami!
Sebelum kita menyimpulkan siri ini, kita akan melihat akhir demo ini dan melihat apa yang boleh dilakukan untuk memperbaikinya dan apakah batasannya.
Secara keseluruhan, ini adalah demo yang agak asas. Kami hanya berlari melalui sintaks asas dan konsep dan memalsukannya ke dalam contoh yang boleh dijalankan. Seperti yang kita lihat sebelum ini, beberapa kawasan boleh diperbaiki untuk menjadikannya lebih fleksibel.
kita perlu mempertimbangkan menyediakan keupayaan mencari kriteria "add-on". Pelaksanaan semasa kami mengehadkan carian aspek untuk digunakan pada asal sahaja, bukannya data yang disaring. Ini adalah peningkatan yang paling penting yang boleh saya fikirkan.
kami mengambil data dari pelayan MySQL setiap kali.
Aplikasi ini menggunakan Silex sebagai rangka kerja. Bagi mana-mana rangka kerja masuk seperti Silex, Symfony, Laravel, index.php (atau app.php) dipanggil setiap kali laluan hendaklah dianalisis dan fungsi pengawal akan dipanggil.
Melihat kod dalam index.php kami, kami akan melihat bahawa ini juga bermakna garis di bawah kod:
<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>
<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>
Kami menyimpan beberapa kenyataan SQL yang dilaksanakan di sisi pelayan ketika kami sedang membina aspek. Daripada lulus 1 pilih pertanyaan dan 3 kumpulan yang berbeza dengan pertanyaan dengan penyataan yang sama, kami hanya mengeluarkan satu pertanyaan pilih dengan pernyataan di mana dan menggunakan pinq untuk memberikan maklumat agregat.
Kesimpulan
Pengarang Pinq kini sedang menjalankan pelepasan versi utama seterusnya (versi 3). Saya harap ia dapat lebih kuat.
Jangan ragu untuk meninggalkan komen dan pemikiran anda di bawah!
Soalan Lazim (Soalan Lazim) Mengenai Pinq dan Carian Facete
Bagaimana PINQ mengendalikan set data yang besar? Ia melakukan ini dengan menggunakan strategi penilaian malas, yang bermaksud bahawa ia hanya memproses data apabila ia benar -benar diperlukan. Ini dapat meningkatkan prestasi dengan ketara apabila bekerja dengan set data yang besar. Pertama, ia memudahkan proses mewujudkan pertanyaan yang kompleks, yang dapat menjimatkan masa dan usaha pemaju. Kedua, ia menyediakan bahasa pertanyaan yang kuat dan fleksibel yang boleh mengendalikan pelbagai jenis data dan struktur. Akhirnya, ia berdasarkan PHP, yang merupakan bahasa pengaturcaraan yang digunakan secara meluas, menjadikannya lebih mudah bagi pemaju untuk belajar dan menggunakan. 🎜> PINQ direka untuk menjadi intuitif dan mudah digunakan, menjadikannya sesuai untuk kedua -dua pemula dan pemaju yang berpengalaman. Walau bagaimanapun, beberapa pengetahuan tentang PHP dan bahasa pertanyaan bermanfaat apabila menggunakan pinq.
Bolehkah pinq digunakan untuk carian masa nyata?
Atas ialah kandungan terperinci PINQ - querify dataset anda - Carian Faceted. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!