Lihat presentasi saya Pencarian Teks Lengkap Praktis di MySQL .
Saya membandingkan:
LIKE
predikat- Ekspresi reguler
predikat (tidak lebih baik dari
LIKE
) - MyISAM FULLTEXT pengindeksan
- Penelusuran Sphinx
- Apache Lucene
- Pengindeksan terbalik
- Google Mesin Telusur Khusus
Hari ini yang akan saya gunakan adalah Apache Solr , yang menempatkan Lucene ke dalam layanan dengan banyak fitur dan alat tambahan.
Re komentar Anda:Aha, oke, tidak. Tak satu pun dari kemampuan pencarian teks lengkap yang saya sebutkan akan membantu, karena mereka semua mengasumsikan semacam batasan kata
Cara lain untuk menemukan substring arbitrer secara efisien adalah N-gram mendekati. Pada dasarnya, buat indeks dari semua kemungkinan urutan huruf N dan arahkan ke string di mana setiap urutan masing-masing muncul. Biasanya ini dilakukan dengan N=3, atau trigram , karena ini adalah titik kompromi antara mencocokkan substring yang lebih panjang dan menjaga indeks ke ukuran yang dapat dikelola.
Saya tidak tahu database SQL mana pun yang mendukung pengindeksan N-gram secara transparan, tetapi Anda dapat mengaturnya sendiri menggunakan indeks terbalik :
create table trigrams (
trigram char(3) primary key
);
create table trigram_matches (
trigram char(3),
document_id int,
primary key (trigram, document_id),
foreign key (trigram) references trigrams(trigram),
foreign key (document_id) references mytable(document_id)
);
Sekarang isi dengan cara yang sulit:
insert into trigram_matches
select t.trigram, d.document_id
from trigrams t join mytable d
on d.textcolumn like concat('%', t.trigram, '%');
Tentu saja ini akan memakan waktu cukup lama! Namun setelah selesai, Anda dapat menelusuri lebih cepat:
select d.*
from mytable d join trigram_matches t
on t.document_id = d.document_id
where t.trigram = 'abc'
Tentu saja Anda bisa mencari pola yang lebih panjang dari tiga karakter, tetapi indeks terbalik masih banyak membantu mempersempit pencarian Anda:
select d.*
from mytable d join trigram_matches t
on t.document_id = d.document_id
where t.trigram = 'abc'
and d.textcolumn like '%abcdef%';