Cari¶
Sebuah tugas umum untuk aplikasi jaringan adalah untuk mencari beberapa data dalam basisdata dengan masukan pengguna. Dalam sebuah kasus sederhana, ini dapat menyaring daftar dari obyek berdasarkan sebuah kategori. Kasus penggunaan lebih rumit mungkin membutuhkan pencarian dengan berat, kategori, penyorotan, banyak bahasa, dan seterusnya. Dokumen ini menjelaskan beberapa dari kemungkinan kasus penggunaan dan alat-alat anda dapat gunakan.
Kita akan mengacu model sama digunakan dalam Membuat query.
Kasus Penggunaan¶
Standar permintaan kata demi kata¶
Text-based fields have a selection of matching operations. For example, you may wish to allow lookup up an author like so:
>>> Author.objects.filter(name__contains='Terry')
[<Author: Terry Gilliam>, <Author: Terry Jones>]
Ini adalah pemecahan sangat rapuh ketika itu membutuhkan pengguna mengetahui substring tepat dari nama penulis. Pendekatan terbaik berupa pencocokan kasus-tidak-peka (icontains
), tetapi ini hanya sedikti lebih baik.
Fungsi-fungsi perbandingan tingkat lanjut lebih banyak basisdata¶
Jika anda sedang menggunakan PostgreSQL, Django menyediakan a selection of database specific tools 1 untuk mengizinkan anda mengungkit lebih rumit pilihan permintaan. Basisdata lain mempunyai pemilihan berbeda dari alat-alat, kemungkinan melalui plugin atau fungsi ditentukan-pengguna. Django tidak menyertakan dukungan apapun untuk mereka pada saat ini. Kami akan menggunakan beberapa contoh dari PostgreSQL untuk menunjukkan hal dari kegunaan basisdata mungkin dimiliki.
Pencarian dalam basisdata lain
Semua alat-alat pencarian disediakan oleh django.contrib.postgres
dibangun seluruhnya pada API umum seperti custom lookups 1 dan database functions 2. Bergantung pada basisdata anda, anda harus dapat membangun permintaan untuk mengizinkan API yang mirip. Jika ada hal-hal khususyang tidak dapat dicapai cara ini, harap buka sebuah tiket.
Dalam contoh diatas, kami menentukan bahwa pencarian kasus-tidak-peka akan lebih berguna. Ketika berurusan dengan nama-nama bukan-Inggris, perbaikan lebih lanjut adalah menggunakan unaccented comparison 1
:
>>> Author.objects.filter(name__unaccent__icontains='Helen')
[<Author: Helen Mirren>, <Author: Helena Bonham Carter>, <Author: Hélène Joy>]
Ini menunjukkan masalah lain, dimana kami sedang mencocokkan terhadap pengejaan berbeda dari nama. Dalam kasus ini kami mempunyai asimetris sekalipun - sebuah pencarian untuk Helen
akan mengambil Helena
atau Hélène
, tetapi bukan kebalikannya. Pilihan lain akan menggunakan perbandingan trigram_similar
, yang membandingkan urutan huruf.
Sebagai contoh:
>>> Author.objects.filter(name__unaccent__lower__trigram_similar='Hélène')
[<Author: Helen Mirren>, <Author: Hélène Joy>]
Now we have a different problem - the longer name of "Helena Bonham Carter" doesn't show up as it is much longer. Trigram searches consider all combinations of three letters, and compares how many appear in both search and source strings. For the longer name, there are more combinations that don't appear in the source string, so it is no longer considered a close match.
Pilihan benar dari fungsi perbandingan disini tergantung pada kumpulan data tertentu anda, sebagai contoh bahasa digunakan dan jenis dari teks sedang diari Semua contoh-contoh kami telah lihat adalah pada string pendek dimana pengguna mungkin memasukkan sesuatu mendekatkan (dengan meragamkan pengertian) pada sumber data.
Pencarian berdasarkan-dokumen¶
Standard database operations stop being a useful approach when you start considering large blocks of text. Whereas the examples above can be thought of as operations on a string of characters, full text search looks at the actual words. Depending on the system used, it's likely to use some of the following ideas:
- Mengabaikan "kata berhenti" seperti "a", "the", "and".
- Menghentikan kata-kata, sehingga "pony" dan "ponies" dianggap sama.
- Bobot kata-kata berdasarkan pada kriteria berbeda seperti sebagaimana sering mereka muncul dalam teks, atau kepentingan dari bidang-bidang, seperti judul atau katakunci, yang mereka muncul.
Ada banyak cara lain untuk menggunakan perangkat lunak pencarian, beberapa dari paling terkemuka adalah Elastic dan Solr. Ini adalah pemecahan pencarian berdasarkan-dokumen penuh. Untuk menggunakan mereka dengan data dari model-model Django, anda akan butuh lapisan yang menterjemahkan data anda kedalam dokumen tekstual, termasuk acuan-kembali ke id basisdata. Ketika sebuah pencarian menggunakan mesin mengembalikan dokumen tertentu, anda dapat kemudian melihat itu dalam basisdata. Ada beragam pustaka-pustaka pihak-ketiga yang dirancang membantu dengan pengolahan ini.
Dukungan PostgreSQL¶
PostgreSQL mempunyai penerapan pencarian teks penuh siap pakai sendiri. Selagi tidak sekuat beberapa mesin pencari lain, itu mempunyai keuntungan dari menjadi didalam basisdata anda dan sehingga dapat dengan mudah dipadukan dengan permintaan penghubung lain seperti kategorisasi.
The django.contrib.postgres
module provides some helpers to make these
queries. For example, a query might select all the blog entries which mention
"cheese":
>>> Entry.objects.filter(body_text__search='cheese')
[<Entry: Cheese on Toast recipes>, <Entry: Pizza recipes>]
Anda dapat juga menyaring pada perpaduan pada bidang dan pada model terkait:
>>> Entry.objects.annotate(
... search=SearchVector('blog__tagline', 'body_text'),
... ).filter(search='cheese')
[
<Entry: Cheese on Toast recipes>,
<Entry: Pizza Recipes>,
<Entry: Dairy farming in Argentina>,
]
Lihat dokumen contrib.postgres
Pencarian teks penuh untuk rincian lengkap.