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¶
Bidang-bidang berdasarkan-teks mempunyai pilihan dari tindakan pencocokan sederhana. Sebagai contoh, anda mungkin ingin mengizinkan pencarian seorang penulis seperti itu:
>>> 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>]
Sekarang kami mempunyai masalah berbeda - nama panjang dari "Helena Bonham Carter" tidak menampilan seperti itu lebih panjang. Pencarian Trigram mempertimbangkan semua perpaduan dari tiga huruf, dan membandingkan seberapa banyak muncul dalam kedua pencarian dan sumber string. Untuk nama terpanjang, ada perpaduan lebih yang muncul dalam string sumber jadi itu tidak lagi dipertimbangkan pencocokan tertutup.
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¶
Tindakan basisdata sederhana adalah terlalu sederhana pada pendekatan ketika anda mulai mempertimbangkan blok-blok besar dari teks. Dimana contoh-contoh diatas dapat dipikirkan sebagai tindakan-tindakan pada string dari karakter, pencarian teks penuh mencari kata sebenarnya. Tergantung pada sistem digunakan, itu mungkin menggunakan beberapa dari ide-ide berikut:
- 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.
Modul django.contrib.postgres
menyediakan beberapa pembantu untuk membuat perubahan permintaan ini. Sebagai contoh, permintaan sederhana mungkin memilih semua masukan blog yang menyebut "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
Full text search untuk rincian lengkap.