Saya baru-baru ini mulai menggunakan ElasticSearch dan sepertinya saya tidak dapat membuatnya mencari bagian kata.
Contoh: Saya punya tiga dokumen dari couchdb saya yang diindeks di ElasticSearch:
{
"_id" : "1",
"name" : "John Doeman",
"function" : "Janitor"
}
{
"_id" : "2",
"name" : "Jane Doewoman",
"function" : "Teacher"
}
{
"_id" : "3",
"name" : "Jimmy Jackal",
"function" : "Student"
}
Jadi sekarang, saya ingin mencari semua dokumen yang mengandung "Doe"
curl http://localhost:9200/my_idx/my_type/_search?q=Doe
Itu tidak menghasilkan hit. Tetapi jika saya mencari
curl http://localhost:9200/my_idx/my_type/_search?q=Doeman
Itu mengembalikan satu dokumen (John Doeman).
Saya telah mencoba menetapkan analisator dan filter yang berbeda sebagai properti indeks saya. Saya juga telah mencoba menggunakan kueri penuh yang meledak (misalnya:
{
"query": {
"term": {
"name": "Doe"
}
}
}
) Tapi sepertinya tidak ada yang berhasil.
Bagaimana saya dapat membuat ElasticSearch menemukan John Doeman dan Jane Doewoman ketika saya mencari "Doe"?
MEMPERBARUI
Saya mencoba menggunakan tokenizer dan filter nGram, seperti yang diusulkan Igor, seperti ini:
{
"index": {
"index": "my_idx",
"type": "my_type",
"bulk_size": "100",
"bulk_timeout": "10ms",
"analysis": {
"analyzer": {
"my_analyzer": {
"type": "custom",
"tokenizer": "my_ngram_tokenizer",
"filter": [
"my_ngram_filter"
]
}
},
"filter": {
"my_ngram_filter": {
"type": "nGram",
"min_gram": 1,
"max_gram": 1
}
},
"tokenizer": {
"my_ngram_tokenizer": {
"type": "nGram",
"min_gram": 1,
"max_gram": 1
}
}
}
}
}
Masalah yang saya alami sekarang adalah setiap query mengembalikan SEMUA dokumen. Ada petunjuk? Dokumentasi ElasticSearch tentang penggunaan nGram tidak bagus ...
sumber
Jawaban:
Saya menggunakan nGram juga. Saya menggunakan tokenizer standar dan nGram hanya sebagai filter. Ini pengaturan saya:
Biarkan Anda menemukan bagian kata hingga 50 huruf. Sesuaikan max_gram yang Anda butuhkan. Dalam bahasa Jerman kata-kata bisa menjadi sangat besar, jadi saya mengaturnya ke nilai yang tinggi.
sumber
Pencarian dengan wildcard terkemuka dan tertinggal akan sangat lambat pada indeks besar. Jika Anda ingin dapat mencari dengan awalan kata, hapus wildcard terkemuka. Jika Anda benar-benar perlu menemukan substring di tengah kata, Anda akan lebih baik menggunakan tokenizer ngram.
sumber
Saya pikir tidak perlu mengubah pemetaan apa pun. Coba gunakan query_string , itu sempurna. Semua skenario akan berfungsi dengan penganalisa standar standar:
Kami memiliki data:
Skenario 1:
Tanggapan:
Skenario 2:
Tanggapan:
Skenario 3:
Tanggapan:
EDIT - Implementasi yang sama dengan pencarian elastis data pegas https://stackoverflow.com/a/43579948/2357869
Satu lagi penjelasan bagaimana query_string lebih baik daripada yang lain https://stackoverflow.com/a/43321606/2357869
sumber
tanpa mengubah pemetaan indeks Anda, Anda bisa melakukan permintaan awalan sederhana yang akan melakukan pencarian parsial seperti yang Anda harapkan
yaitu.
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-prefix-query.html
sumber
Coba solusinya dengan dijelaskan di sini: Pencarian Substring yang Tepat dalam ElasticSearch
Untuk mengatasi masalah penggunaan disk dan masalah istilah pencarian yang terlalu panjang, digunakan karakter pendek dengan 8 karakter ngram (dikonfigurasi dengan: "max_gram": 8 ). Untuk mencari istilah dengan lebih dari 8 karakter, ubah pencarian Anda menjadi boolean DAN kueri yang mencari setiap substring 8 karakter yang berbeda dalam string itu. Misalnya, jika pengguna mencari halaman besar (string 10 karakter), pencariannya adalah:
"Arge ya DAN arge yar DAN rge yard .
sumber
min_gram
danmax_gram
sepertinya itu akan tergantung secara linear pada ukuran nilai bidang dan rentangmin
danmax
. Seberapa disukai menggunakan sesuatu seperti ini?ngram
filter ini menggunakan tokenizer? dapatkah Anda tidak hanya memilikinya sebagai tokenizer dan kemudian menerapkan filter huruf kecil ...index_ngram: { type: "custom", tokenizer: "ngram_tokenizer", filter: [ "lowercase" ] }
Saya mencobanya dan tampaknya memberikan hasil yang sama dengan menggunakan uji penganalisa apiJika Anda ingin menerapkan fungsi autocomplete, maka Completion Suggester adalah solusi yang paling rapi. Posting blog berikutnya berisi deskripsi yang sangat jelas bagaimana ini bekerja.
Dalam dua kata, ini adalah struktur data dalam memori yang disebut FST yang berisi saran yang valid dan dioptimalkan untuk pengambilan cepat dan penggunaan memori. Pada dasarnya, ini hanyalah sebuah grafik. Misalnya, dan FST mengandung kata-kata
hotel
,marriot
,mercure
,munchen
danmunich
akan terlihat seperti ini:sumber
Anda dapat menggunakan regexp.
jika Anda menggunakan kueri ini:
Anda akan memberikan semua data yang namanya dimulai dengan "J". Pertimbangkan Anda ingin menerima hanya dua catatan pertama yang namanya diakhiri dengan "man" sehingga Anda dapat menggunakan kueri ini:
dan jika Anda ingin menerima semua catatan yang ada namanya "m", Anda dapat menggunakan pertanyaan ini:
Ini bekerja untuk saya. Dan saya harap jawaban saya cocok untuk menyelesaikan masalah Anda.
sumber
Menggunakan kartu wil (*) mencegah perhitungan skor
sumber
Saya menggunakan ini dan membuat saya bekerja
sumber
Lupakan.
Saya harus melihat dokumentasi Lucene. Sepertinya saya bisa menggunakan wildcard! :-)
lakukan triknya!
sumber