Cari di sistem informasi perusahaan - sudah dari frasa ini sendiri terjebak di mulut. Baik jika Anda memilikinya, Anda bahkan tidak perlu memikirkan pengalaman pengguna yang positif. Bagaimana cara membalikkan sikap pengguna yang dimanjakan oleh mesin pencari dan menciptakan produk yang cepat, akurat, dan dapat dimengerti dengan sempurna? Kita perlu mengambil bagian yang bagus dari Elasticsearch, beberapa layanan cerdas dan mengaduknya dalam panduan ini.
Ada banyak artikel tentang cara mempercepat pencarian teks lengkap berdasarkan Elasticsearch ke database yang ada. Tetapi jelas tidak ada cukup artikel tentang cara melakukan pencarian yang benar-benar cerdas.
Pada saat yang sama, frasa "Pencarian Cerdas" itu sendiri telah berubah menjadi kata kunci dan digunakan untuk tempat itu dan bukan. Jadi apa yang harus dilakukan mesin pencari agar dianggap pintar? Pada akhirnya, ini dapat digambarkan sebagai memberikan hasil yang benar-benar dibutuhkan pengguna, bahkan jika hasil ini tidak cukup cocok dengan teks permintaan. Mesin pencari populer seperti Google dan Yandex melangkah lebih jauh dan tidak hanya menemukan informasi yang mereka butuhkan, tetapi langsung menjawab pertanyaan pengguna.
Oke, kami tidak akan langsung menyapu keputusan ultimatum, tetapi apa yang bisa dilakukan untuk membawa pencarian teks lengkap biasa lebih dekat ke yang cerdas ?
Unsur kecerdasan
Pencarian cerdas - ini hanya kasus ketika kuantitas bisa masuk ke kualitas dan banyak fitur kecil dan cukup sederhana dapat membentuk rasa sihir.
- Koreksi kesalahan pengguna - apakah ini salah ketik, tata letak yang salah, atau mungkin permintaan dengan hasil yang sedikit mencurigakan, tetapi mirip dengan permintaan yang memiliki informasi lebih banyak.
- Untuk
th Obrolan NLP (pemrosesan bahasa alami, bukan apa yang Anda pikirkan) - jika pengguna memasukkan penawaran komersial untuk tahun lalu , apakah ia benar-benar ingin mencari kata-kata ini dalam teks semua dokumen atau apakah ia benar-benar hanya membutuhkan penawaran komersial dan hanya tahun lalu ? - Memprediksi input berdasarkan permintaan sebelumnya atau dokumen populer.
- Presentasi hasil adalah sorotan yang biasa dari fragmen yang ditemukan, informasi tambahan tergantung pada apa yang Anda cari. Karena proposal komersial diperlukan pada paragraf sebelumnya, mungkin masuk akal untuk segera menunjukkan subjek proposal dan dari mana organisasi itu berasal?
- Penelusuran yang mudah - kemampuan untuk mempersempit kueri penelusuran menggunakan filter tambahan, aspek.
Pendahuluan
Ada DIRECTUM ECM dengan banyak dokumen di dalamnya. Dokumen terdiri dari kartu dengan meta-informasi dan badan, yang dapat memiliki beberapa versi.
Tujuannya adalah untuk dengan cepat dan mudah mencari informasi dalam dokumen-dokumen ini dengan cara yang biasa untuk pengguna mesin pencari.
Pengindeksan
Untuk mencari sesuatu dengan baik, Anda harus mengindeksnya dengan baik terlebih dahulu.
Dokumen dalam ECM tidak statis, pengguna memodifikasi teks, membuat versi baru, mengubah data dalam kartu; dokumen baru terus-menerus dibuat dan yang lama terkadang dihapus.
Untuk menjaga informasi terkini di Elasticsearch, dokumen harus terus-menerus diindeks ulang. Untungnya, ECM sudah memiliki antrian acara asinkron sendiri, jadi ketika Anda mengubah dokumen, tambahkan saja ke antrian untuk pengindeksan.
Memetakan dokumen ECM ke dokumen Elasticsearch
Badan dokumen di ECM dapat memiliki beberapa versi. Dalam Elasticsearch, ini bisa dianggap sebagai array objek bersarang, tetapi kemudian menjadi tidak nyaman untuk bekerja dengannya - menjadi lebih sulit untuk menulis kueri, ketika mengubah salah satu versi, Anda perlu mengindeks ulang semuanya, versi berbeda dari dokumen yang sama tidak dapat disimpan dalam indeks yang berbeda (mengapa ini diperlukan - di bagian selanjutnya). Karenanya, kami mendenormalisasi satu dokumen dari ECM menjadi beberapa dokumen Elasticsearch dengan kartu yang sama tetapi dengan badan yang berbeda.
Selain kartu dan isi, berbagai informasi layanan ditambahkan ke dokumen Elasticsearch, yang layak disebutkan secara terpisah:
- daftar ID grup dan pengguna yang memiliki hak atas dokumen - untuk pencarian dengan hak;
- jumlah panggilan ke dokumen - untuk mencari relevansi;
- waktu pengindeksan terakhir.
Komposisi Indeks
Ya, indeks jamak. Biasanya, beberapa indeks untuk menyimpan informasi yang memiliki arti serupa dalam Elasticsearch hanya digunakan jika informasi ini tidak dapat diubah dan terikat pada beberapa jenis periode waktu, misalnya, log. Kemudian indeks dibuat setiap bulan / hari atau lebih sering tergantung pada intensitas beban. Dalam kasus kami, dokumen apa pun dapat diubah, dan dimungkinkan untuk menyimpan semuanya dalam satu indeks.
Tapi - dokumen dalam sistem bisa dalam bahasa yang berbeda, dan menyimpan data multibahasa di Elasticsearch membawa 2 masalah:
- Batang yang salah. Untuk beberapa kata, basis akan ditemukan dengan benar, untuk beberapa - salah (akan ada kata lain dalam indeks), untuk beberapa - tidak akan ditemukan sama sekali (indeks akan menjadi tersumbat dengan bentuk kata). Untuk beberapa kata dari bahasa yang berbeda dan dengan makna yang berbeda, dasarnya akan sama, dan kemudian arti kata tersebut akan hilang. Penggunaan beberapa stemmer berturut-turut dapat menyebabkan perhitungan tambahan dari basis untuk yang sudah dihitung.
Stamming - menemukan dasar kata. Batang tidak harus menjadi akar kata atau bentuk normalnya. Biasanya sudah cukup untuk kata-kata terkait diproyeksikan ke dalam satu kerangka kerja.
Lemmatization adalah jenis stemming di mana bentuk kata normal (kosa kata) dianggap sebagai dasar.
- Frekuensi kata salah. Beberapa mekanisme penentuan relevansi dalam ES memperhitungkan frekuensi kata yang dicari dalam dokumen (semakin sering, semakin tinggi relevansi) dan frekuensi kata yang dicari dalam indeks (semakin sering, semakin rendah relevansi). Jadi, penyebaran kecil pidato Rusia dalam dokumen bahasa Inggris, ketika dokumen-dokumen bahasa Inggris sebagian besar berada dalam indeks, akan memiliki bobot yang tinggi, tetapi ada baiknya mencampur dokumen-dokumen bahasa Inggris dan Rusia dalam indeks, dan bobotnya akan berkurang.
Masalah pertama dapat dipecahkan untuk kasus ketika bahasa yang berbeda menggunakan set karakter yang berbeda, (dokumen Rusia-Inggris menggunakan huruf Cyrillic dan Latin) - stemmer bahasa hanya akan memproses karakter "mereka".
Hanya untuk menyelesaikan masalah kedua, kami menggunakan pendekatan dengan indeks terpisah untuk setiap bahasa.
Menggabungkan kedua pendekatan, kami memperoleh indeks bahasa, yang tetap mengandung analisis untuk beberapa bahasa yang tidak berpotongan dalam set karakter: Rusia-Inggris (dan secara terpisah Inggris-Rusia), Polandia-Rusia, Jerman-Rusia, Ukraina-Inggris, dll. .
Agar tidak membuat semua kemungkinan indeks sebelumnya, kami menggunakan templat indeks - Elasticsearch memungkinkan Anda menentukan templat yang berisi pengaturan dan pemetaan, dan menentukan pola nama indeks. Saat Anda mencoba untuk mengindeks dokumen ke dalam indeks yang tidak ada, nama yang cocok dengan salah satu pola template, tidak hanya indeks baru akan dibuat, tetapi juga pengaturan dan pemetaan dari template yang sesuai akan diterapkan padanya.
Struktur Indeks
Untuk pengindeksan, kami menggunakan dua analisis sekaligus (melalui multi-bidang): default untuk pencarian dengan frasa persis dan kustom untuk yang lainnya:
"ru_en_analyzer": { "filter": [ "lowercase", "russian_morphology", "english_morphology", "word_delimiter", "ru_en_stopwords" ], "char_filter": [ "yo_filter" ], "type": "custom", "tokenizer": "standard"}
Dengan filter huruf kecil, semuanya jelas, saya akan menceritakan sisanya.
Filter russian_morphology dan english_morphology dimaksudkan untuk analisis morfologis teks Rusia dan Inggris, masing-masing. Mereka bukan bagian dari Elasticsearch dan dimasukkan sebagai bagian dari plugin analisis-morfologi yang terpisah. Ini adalah lemmatizer yang menggunakan pendekatan kosa kata dalam kombinasi dengan beberapa heuristik dan bekerja secara signifikan, JAUH, lebih baik daripada filter bawaan untuk bahasa yang sesuai.
POST _analyze { "analyzer": "russian", "text": " " } >>
Dan:
POST _analyze { "analyzer": "ru_en_analyzer", "text": " " } >>
Filter word_delimiter yang sangat aneh. Ini, misalnya, membantu menghilangkan kesalahan ketik ketika tidak ada ruang setelah titik. Kami menggunakan konfigurasi berikut:
"word_delimiter": { "catenate_all": "true", "type": "word_delimiter", "preserve_original": "true" }
yo_filter memungkinkan Anda mengabaikan perbedaan antara E dan E:
"yo_filter": { "type": "mapping", "mappings": [ " => ", " => " ] }
stop type filter ru_en_stopwords - kamus kata-kata berhenti kami.
Proses pengindeksan
Badan-badan dokumen di ECM, sebagai aturan, file format kantor: .docx, .pdf, dll. Untuk mengekstrak teks, plugin ingest-attachment digunakan dengan pipa berikut:
{ "document_version": { "processors": [ { "attachment": { "field": "content", "target_field": "attachment", "properties": [ "content", "content_length", "content_type", "language" ], "indexed_chars": -1, "ignore_failure": true } }, { "remove": { "field": "content", "ignore_failure": true } }, { "script": { "lang": "painless", "params": { "languages": ["ru", "en" ], "language_delimeter": "_" }, "source": "..." } }, { "remove": { "field": "attachment", "ignore_failure": true } } ] } }
Dari yang tidak biasa dalam pipa, mengabaikan kesalahan tidak adanya tubuh (ini terjadi untuk dokumen yang dienkripsi) dan menentukan indeks target berdasarkan bahasa teks. Yang terakhir ini dilakukan dalam naskah tanpa rasa sakit, tubuh yang akan saya berikan secara terpisah, karena karena pembatasan JSON, harus ditulis dalam satu baris. Bersama dengan kesulitan debugging (cara yang disarankan adalah melemparkan pengecualian di sana-sini), itu benar-benar berubah menjadi menyakitkan.
if (ctx.attachment != null) { if (params.languages.contains(ctx.attachment.language)) ctx._index = ctx._index + params.language_delimeter + ctx.attachment.language; if (ctx.attachment.content != null) ctx.content = ctx.attachment.content; if (ctx.attachment.content_length != null) ctx.content_length = ctx.attachment.content_length; if (ctx.attachment.content_type != null) ctx.content_type = ctx.attachment.content_type; if (ctx.attachment.language != null) ctx.language = ctx.attachment.language; }
Jadi, kami selalu mengirim dokumen ke index_name . Jika bahasa tidak didefinisikan atau tidak didukung, maka dokumen mengendap dalam indeks ini, jika tidak jatuh ke index_name_language .
Kami tidak menyimpan tubuh asli file, tetapi bidang _source diaktifkan, karena diperlukan untuk memperbarui sebagian dokumen dan menyoroti yang ditemukan.
Jika hanya kartu yang telah berubah sejak indeksasi terakhir, maka kami menggunakan API Pembaruan Menurut Permintaan tanpa pipa untuk memperbaruinya. Ini memungkinkan, pertama, untuk tidak menyeret badan dokumen yang berpotensi besar dari ECM, dan kedua, secara signifikan mempercepat pembaruan di sisi Elasticsearch - Anda tidak perlu mengekstraksi teks dokumen dari format kantor, yang sangat padat sumber daya.
Dengan demikian, sama sekali tidak ada pembaruan dokumen di Elasticsearch, secara teknis, ketika memperbarui dari indeks, dokumen lama dikeluarkan, diubah dan sepenuhnya diindeks lagi.
Tetapi jika badan berubah, maka dokumen lama umumnya dihapus dan diindeks dari awal. Ini memungkinkan dokumen untuk berpindah dari satu indeks bahasa ke yang lain.
Cari
Untuk memudahkan deskripsi, saya akan memberikan tangkapan layar dari hasil akhir

Teks lengkap
Jenis utama kueri yang kami miliki adalah Pertanyaan Kueri String Sederhana :
"simple_query_string": { "fields": [ "card.d*.*_text", "card.d*.*_text.exact", "card.name^2", "card.name.exact^2", "content", "content.exact" ], "query": " ", "default_operator": "or", "analyze_wildcard": true, "minimum_should_match": "-35%", "quote_field_suffix": ".exact" }
di mana .exact adalah bidang yang diindeks oleh parser default . Pentingnya nama dokumen dua kali lebih tinggi dari bidang lainnya. Kombinasi "default_operator": "or"
dan "minimum_should_match": "-35%"
memungkinkan Anda menemukan dokumen yang tidak mengandung hingga 35% dari kata-kata yang dicari.
Sinonim
Secara umum, analisis yang berbeda digunakan untuk pengindeksan dan pencarian, tetapi satu-satunya perbedaan di dalamnya adalah penambahan filter untuk menambahkan sinonim ke permintaan pencarian:
"search_analyzer": { "filter": [ "lowercase", "russian_morphology", "english_morphology", "synonym_filter", "word_delimiter", "ru_en_stopwords" ], "char_filter": [ "yo_filter" ], "tokenizer": "standard" }
"synonym_filter": { "type": "synonym_graph", "synonyms_path": "synonyms.txt" }
Hak akuntansi
Untuk pencarian berbasis hak, kueri utama tertanam di Bool Query , dengan tambahan filter:
"bool": { "must": [ { "simple_query_string": {...} } ], "filter": [ { "terms": { "rights": [ ] } } ] }
Seperti yang kita ingat dari bagian pengindeksan, indeks memiliki bidang dengan ID pengguna dan grup yang memiliki hak atas dokumen. Jika ada persimpangan bidang ini dengan array yang diteruskan, maka ada hak.
Penyesuaian Relevansi
Secara default, Elasticsearch mengevaluasi relevansi hasil menggunakan algoritma BM25 menggunakan kueri dan teks dokumen. Kami memutuskan bahwa tiga faktor lagi harus memengaruhi penilaian kepatuhan dengan hasil yang diinginkan dan aktual:
- waktu pengeditan dokumen terakhir - semakin jauh di masa lalu, semakin kecil kemungkinan dokumen ini diperlukan;
- jumlah panggilan ke dokumen - semakin banyak, semakin besar kemungkinan dokumen ini dibutuhkan;
Versi tubuh ECM memiliki beberapa kemungkinan status: sedang dikembangkan, operasional, dan tidak digunakan lagi. Adalah logis bahwa akting lebih penting daripada yang lain.
Anda dapat mencapai efek ini dengan bantuan Kueri Skor Fungsi :
"function_score": { "functions": [ { "gauss": { "modified_date": { "origin": "now", "scale": "1095d", "offset": "31d", "decay": 0.5 } } }, { "field_value_factor": { "field": "access_count", "missing": 1, "modifier": "log2p" } }, { "filter": { "term": { "life_stage_value_id": { "value": "" } } }, "weight": 1.1 } ], "query": { "bool": {...} } }
Akibatnya, ceteris paribus, kami mendapatkan kira-kira ketergantungan berikut dari pengubah peringkat hasil pada tanggal perubahan terakhir X dan jumlah klik Y:
Kecerdasan eksternal
Untuk bagian dari fungsi pencarian cerdas, kita perlu mengekstraksi berbagai fakta dari permintaan pencarian: tanggal dengan aplikasi mereka (kreasi, modifikasi, persetujuan, dll.), Nama organisasi, jenis dokumen yang dicari, dll.
Diminta juga untuk mengklasifikasikan permintaan ke dalam kategori tertentu, misalnya, dokumen menurut organisasi, oleh karyawan, peraturan, dll.
Dua operasi ini dilakukan oleh Modul Cerdas ECM - DIRECTUM Ario .
Proses pencarian cerdas
Sudah saatnya untuk mempertimbangkan secara lebih rinci mekanisme apa yang diterapkan unsur-unsur intelijen.
Koreksi kesalahan pengguna
Ketepatan tata letak ditentukan berdasarkan pada model bahasa trigram - untuk sebuah garis, dihitung seberapa besar kemungkinannya memenuhi urutan tiga karakternya dalam teks dalam bahasa Inggris dan Rusia. Jika tata letak saat ini dianggap kecil kemungkinannya, maka, pertama, petunjuk dengan tata letak yang benar ditampilkan:

dan kedua, langkah selanjutnya dari pencarian dilakukan dengan tata letak yang benar:

Dan jika tidak ada yang dapat ditemukan dengan tata letak yang diperbaiki, maka pencarian dimulai dengan baris asli.
Koreksi kesalahan ketik diimplementasikan menggunakan Phrase Suggester . Ada masalah dengannya - jika Anda menjalankan kueri pada beberapa indeks secara bersamaan, maka saran mungkin tidak mengembalikan apa pun, sementara jika Anda mengeksekusi hanya pada satu indeks, ada hasilnya. Ini diperlakukan dengan menetapkan kepercayaan = 0, tetapi kemudian menyarankan menyarankan mengganti kata-kata dengan bentuk normal. Setuju, akan aneh ketika Anda mencari "huruf a " untuk mendapatkan jawaban dalam semangat: Mungkin Anda sedang mencari surat tentang ?
Ini dapat dielakkan dengan menggunakan dua konfirmasi dalam permintaan:
"suggest": { "content_suggest": { "text": " ", "phrase": { "collate": { "query": { {{suggestion}} } }, } }, "check_suggest": { "text": "", "phrase": { "collate": { "query": { {{suggestion}} - ({{source_query}}) }, "params": { "source_query": " " } }, } } }
Dari parameter umum yang digunakan
"confidence": 0.0, "max_errors": 3.0, "size": 1
Jika pendapat pertama mengembalikan hasil, tetapi yang kedua tidak, maka hasil ini adalah string asli itu sendiri, mungkin dengan kata-kata dalam bentuk lain, dan tidak perlu menunjukkan petunjuk. Jika petunjuk masih diperlukan, frasa pencarian asli menyatu dengan petunjuk. Ini terjadi dengan mengganti hanya kata-kata yang diperbaiki dan hanya kata-kata yang pemeriksa ejaan (menggunakan Hunspell) anggap salah.
Jika pencarian pada string sumber menghasilkan 0 hasil, maka itu digantikan oleh string yang diperoleh oleh gabungan dan pencarian dilakukan lagi:

Jika tidak, string prompt yang dihasilkan hanya dikembalikan sebagai prompt untuk pencarian:

Klasifikasi kueri dan ekstraksi fakta
Seperti yang saya sebutkan, kami menggunakan DIRECTUM Ario, yaitu layanan klasifikasi teks dan layanan ekstraksi fakta. Untuk melakukan ini, kami memberikan pertanyaan pencarian anonim kepada analis dan daftar fakta yang kami minati. Berdasarkan pertanyaan dan pengetahuan tentang dokumen apa yang ada dalam sistem, analis mengidentifikasi beberapa kategori dan melatih layanan klasifikasi untuk menentukan kategori sesuai dengan teks kueri. Berdasarkan kategori dan daftar fakta yang dihasilkan, kami merumuskan aturan untuk menggunakan fakta-fakta ini. Misalnya, frasa untuk tahun terakhir dalam kategori Semua orang dianggap sebagai tanggal pembuatan dokumen, dan dalam kategori Menurut organisasi - tanggal pendaftaran. Pada saat yang sama, yang dibuat tahun lalu harus dalam kategori apa pun jatuh pada tanggal pembuatan.
Dari sisi pencarian - mereka membuat konfigurasi di mana mereka mendaftarkan kategori, fakta mana yang diterapkan pada filter facet mana.
Input selesai
Selain koreksi tata letak yang telah disebutkan, pencarian sebelumnya dari pengguna dan dokumen publik jatuh ke pelengkapan otomatis.

Mereka diimplementasikan menggunakan jenis lain Suggester - Completion Suggester , tetapi masing-masing memiliki nuansa tersendiri.
Pelengkapan Otomatis: Riwayat Pencarian
Ada jauh lebih sedikit pengguna di ECM daripada mesin pencari, dan mengalokasikan cukup pertanyaan umum untuk mereka mengapa jamur lenin tidak mungkin. Perlihatkan segala sesuatu secara berturut-turut juga tidak layak karena pertimbangan privasi. Completion Suggester yang biasa hanya dapat mencari seluruh kumpulan dokumen dalam indeks, tetapi Context Suggester datang untuk menyelamatkan - cara untuk mengatur konteks untuk setiap petunjuk dan memfilter menurut konteks ini. Jika nama pengguna digunakan sebagai konteks, maka hanya riwayatnya yang dapat ditampilkan kepada semua orang.
Anda juga perlu memberi pengguna kesempatan untuk menghapus prompt yang membuatnya malu. Sebagai kunci untuk penghapusan, kami menggunakan teks nama pengguna dan petunjuk. Sebagai hasilnya, untuk indeks dengan petunjuk, kami mendapatkan pemetaan yang sedikit terduplikasi:
"mappings": { "document": { "properties": { "input": { "type": "keyword" }, "suggest": { "type": "completion", "analyzer": "simple", "preserve_separators": true, "preserve_position_increments": true, "max_input_length": 50, "contexts": [ { "name": "user", "type": "CATEGORY" } ] }, "user": { "type": "keyword" } } } }
Bobot untuk setiap petunjuk baru disetel ke petunjuk dan bertambah setiap kali Anda memasukkannya kembali menggunakan API Pembaruan Dengan Kueri dengan skrip ctx._source.suggest.weight++
sangat sederhana.
Pelengkapan Otomatis: Dokumen
Tetapi mungkin ada banyak dokumen dan kemungkinan kombinasi hak. Karenanya, di sini, sebaliknya, kami memutuskan untuk tidak melakukan pemfilteran dengan hak saat pelengkapan otomatis, tetapi hanya mengindeks dokumen publik. Ya, dan Anda tidak perlu menghapus kiat individual dari indeks ini. Tampaknya implementasi dalam segala hal lebih mudah daripada yang sebelumnya, jika bukan karena dua poin:
Yang pertama - Completion Suggester hanya mendukung pencarian awalan, dan pelanggan senang menetapkan nomor item untuk semuanya, dan beberapa .01.01
saat Anda mengetik kueri Tidak .01.01
. Di sini, bersama dengan nama lengkapnya, Anda juga dapat mengindeks n-gram yang diturunkan darinya:
{ "extension": "pdf", "name": ".01.01 ", "suggest": [ { "input": "", "weight": 70 }, { "input": " ", "weight": 80 }, { "input": " ", "weight": 90 }, { "input": ".01.01 ", "weight": 100 } ] }
Ini tidak terlalu kritis dengan cerita, namun pengguna yang sama memasuki kira-kira baris yang sama jika dia mencari sesuatu lagi. Mungkin
Yang kedua - secara default, semua tips sama, tetapi kami ingin membuat beberapa dari mereka lebih sama dan lebih disukai sehingga ini konsisten dengan peringkat hasil pencarian. Untuk melakukan ini, ulangi secara kasar fungsi gauss dan field_value_factor yang digunakan dalam Kueri Skor Fungsi .
Ternyata di sini adalah pipa seperti itu:
{ "dir_public_documents_pipeline": { "processors": [ ... { "set": { "field": "terms_array", "value": "{{name}}" } }, { "split": { "field": "terms_array", "separator": "\\s+|$" } }, { "script": { "source": "..." } } ] } }
dengan skrip berikut:
Date modified = new Date(0); if (ctx.modified_date != null) modified = new SimpleDateFormat('dd.MM.yyyy').parse(ctx.modified_date); long dayCount = (System.currentTimeMillis() - modified.getTime())/(1000*60*60*24); double score = Math.exp((-0.7*Math.max(0, dayCount - 31))/1095) * Math.log10(ctx.access_count + 2); int count = ctx.terms_array.length; ctx.suggest = new ArrayList(); ctx.suggest.add([ 'input': ctx.terms_array[count - 1], 'weight': Math.round(score * (255 - count + 1)) ]); for (int i = count - 2; i >= 0 ; --i) { if (ctx.terms_array[i].trim() != "") { ctx.suggest.add([ "input": ctx.terms_array[i] + " " + ctx.suggest[ctx.suggest.length - 1].input, "weight": Math.round(score * (255 - i))]); } } ctx.remove('terms_array'); ctx.remove('access_count'); ctx.remove('modified_date');
Mengapa repot-repot dengan saluran pipa tanpa rasa sakit alih-alih menulisnya dalam bahasa yang lebih nyaman? Karena sekarang, menggunakan API Reindex , Anda dapat menyalip isi indeks pencarian ke dalam indeks untuk petunjuk (tentu saja dengan menentukan bidang yang diperlukan saja) hanya dalam satu perintah.
Komposisi dokumen publik yang sangat dibutuhkan tidak sering diperbarui, sehingga perintah ini dapat dibiarkan secara manual.
Menampilkan Hasil
Kategori
Kategori menentukan segi mana yang akan tersedia dan seperti apa potongannya. Itu dapat dideteksi secara otomatis oleh intelijen eksternal atau dipilih secara manual di atas bilah pencarian.
Segi
Aspek adalah hal yang sangat intuitif bagi setiap orang yang perilakunya, dijelaskan oleh aturan yang sangat sepele. Berikut ini beberapa di antaranya:
Nilai facet tergantung pada hasil pencarian, TETAPI dan hasil pencarian tergantung pada aspek yang dipilih. Bagaimana cara menghindari rekursi?
Memilih nilai dalam satu segi tidak memengaruhi nilai-nilai lain dari segi ini, tetapi itu memengaruhi nilai di sisi lain:

- Nilai facet yang dipilih pengguna tidak boleh hilang, bahkan jika pilihan pada facet lain memusnahkannya menjadi 0 atau mereka tidak lagi di atas:

Dalam elastisitas, aspek diwujudkan melalui mekanisme agregasi, tetapi untuk memenuhi aturan yang dijelaskan, agregasi ini harus diinvestasikan satu sama lain dan disaring oleh satu sama lain.
Pertimbangkan fragmen permintaan yang bertanggung jawab untuk ini:
Kode terlalu besar { ... "post_filter": { "bool": { "must": [ { "terms": { "card.author_value_id": [ "1951063" ] } }, { "terms": { "editor_value_id": [ "2337706", "300643" ] } } ] } }, "query": {...} "aggs": { "card.author_value_id": { "filter": { "terms": { "editor_value_id": [ "2337706", "300643" ] } }, "aggs": { "card.author_value_id": { "terms": { "field": "card.author_value_id", "size": 11, "exclude": [ "1951063" ], "missing": "" } }, "card.author_value_id_selected": { "terms": { "field": "card.author_value_id", "size": 1, "include": [ "1951063" ], "missing": "" } } } }, ... "editor_value_id": { "filter": { "terms": { "card.author_value_id": [ "1951063" ] } }, "aggs": { "editor_value_id": { "terms": { "field": "editor_value_id", "size": 11, "exclude": [ "2337706", "300643" ], "missing": "" } }, "editor_value_id_selected": { "terms": { "field": "editor_value_id", "size": 2, "include": [ "2337706", "300643" ], "missing": "" } } } }, ... } }
Apa yang ada di sini itu:
- post_filter memungkinkan Anda untuk memaksakan kondisi tambahan pada hasil permintaan yang sudah selesai dan tidak mempengaruhi hasil agregasi. Kesenjangan rekursi yang sama. Termasuk semua nilai yang dipilih dari semua sisi.
- agregasi tingkat atas, dalam contoh card.author_value_id dan editor_value_id . Masing-masing memiliki:
- memfilter menurut nilai-nilai semua aspek lain, kecuali untuk Anda sendiri;
- agregasi bersarang untuk nilai facet yang dipilih - perlindungan terhadap pemusnahan ;
- agregasi bersarang untuk nilai facet lainnya. Kami menampilkan 10 teratas, dan meminta 11 teratas - untuk menentukan apakah akan menampilkan tombol Tampilkan semua .
Cuplikan
Bergantung pada kategori yang dipilih, cuplikan mungkin terlihat berbeda, misalnya, dokumen yang sama saat mencari dalam suatu kategori
Semua :

dan Karyawan :

Atau ingat, kami ingin melihat subjek dari penawaran komersial dan dari siapa itu datang?

Agar tidak menyeret seluruh kartu dari elastis (ini memperlambat pencarian), Penyaringan sumber digunakan :
{ ... "_source": { "includes": [ "id", "card.name", "card.card_type_value_id", "card.life_stage_value_id", "extension", ... ] }, "query": {...} ... }
Untuk menyorot kata-kata yang ditemukan dalam teks dokumen, stabilo Fast Vector digunakan - sebagai menghasilkan snippet yang paling tepat untuk teks besar, dan untuk nama - Stabilo terpadu - sebagai yang paling sedikit menuntut sumber daya dan struktur indeks:
"highlight": { "pre_tags": [ "<strong>" ], "post_tags": [ "</strong>" ], "encoder": "html", "fields": { "card.name": { "number_of_fragments": 0 }, "content": { "fragment_size": 300, "number_of_fragments": 3, "type": "fvh" } } },
Dalam hal ini, namanya disorot secara keseluruhan, dan dari teks kita mendapatkan hingga 3 fragmen 300 karakter. Teks yang dikembalikan oleh stabilo Fast Vector lebih lanjut dikompresi oleh algoritma darurat untuk mendapatkan keadaan potongan yang diminimalkan.
Runtuh
Secara historis, pengguna ECM ini terbiasa dengan fakta bahwa pencarian mengembalikan dokumen kepada mereka, tetapi pada kenyataannya Elasticsearch mencari di antara versi dokumen . Mungkin ternyata beberapa versi yang hampir identik akan ditemukan pada permintaan yang sama. Ini akan mengacaukan hasil dan membingungkan pengguna. Untungnya, perilaku ini dapat dihindari dengan menggunakan mekanisme Field Collapsing - beberapa versi agregasi ringan yang sudah bekerja pada hasil akhir (dalam hal ini menyerupai post_filter, dua kruk adalah pasangan ). Runtuhnya akan menghasilkan objek runtuh yang paling relevan.
{ ... "query": {...} ... "collapse": { "field": "id" } }
Sayangnya, collapse memiliki sejumlah efek yang tidak menyenangkan, misalnya, berbagai karakteristik numerik dari hasil pencarian terus kembali seolah-olah tidak ada runtuh. Artinya, jumlah hasil, jumlah nilai facet - semua akan sedikit salah, tetapi pengguna biasanya tidak memperhatikan hal ini, seperti halnya pembaca yang lelah, yang kemungkinan besar belum pernah membaca proposal ini sebelumnya.
Akhirnya