Pencarian teks lengkap dengan bobot di luwak

Seperti yang saya ketahui, sejak versi 3.8.9, luwak mendukung pencarian teks lengkap. Namun saya tidak dapat menemukan dokumentasi yang bagus untuk itu!
Saya ingin melakukan sesuatu seperti:

db.collection.ensureIndex(
    // Fields to index
    {
        animal:  "text",
        color:   "text",
        pattern: "text",
        size:    "text"
    },

    // Options
    {
        name: "best_match_index",

        // Adjust field weights (default is 1)
        weights: {
            animal: 5,  // Most relevant search field
            size:   4   // Also relevant
       }
    }
)

Bisakah saya melakukannya dengan luwak murni? Atau saya harus menggunakan beberapa plugin seperti mongoose-text-search? Bagaimana kalau tanpa beban?
Dan bagaimana cara melakukannya?


person Foad Nosrati Habibi    schedule 12.07.2014    source sumber
comment
Sudahkah Anda mencoba memanggil index pada skema untuk menambahkan indeks teks?   -  person JohnnyHK    schedule 12.07.2014
comment
Saya melakukannya dalam skema sebagai indeks: 'teks', tetapi saya ingin mengindeks pada beberapa bidang seperti contoh di atas.   -  person Foad Nosrati Habibi    schedule 12.07.2014
comment
Jangan mendeklarasikannya dalam definisi skema Anda, panggil metode index skema Anda. mongoosejs.com/docs/api.html#schema_Schema-index   -  person JohnnyHK    schedule 13.07.2014
comment
maksud Anda 'skema.index({ hewan: teks, warna: teks, pola: teks, ukuran: teks })' ? Bagaimana dengan berat badan? Dan apakah itu membuat indeks tunggal atau 4 indeks?   -  person Foad Nosrati Habibi    schedule 13.07.2014


Jawaban (4)


Ya, Anda dapat menggunakan pencarian teks lengkap di Mongoose >= 3.8.9. Pertama, sebuah koleksi dapat memiliki paling banyak satu indeks teks (lihat docs). Jadi, untuk menentukan indeks teks untuk beberapa bidang, Anda memerlukan indeks gabungan:

schema.index({ animal: 'text', color: 'text', pattern: 'text', size: 'text' });

Sekarang Anda dapat menggunakan kueri $text operator seperti ini:

Model
    .find(
        { $text : { $search : "text to look for" } }, 
        { score : { $meta: "textScore" } }
    )
    .sort({ score : { $meta : 'textScore' } })
    .exec(function(err, results) {
        // callback
    });

Ini juga akan mengurutkan hasil berdasarkan skor relevansi.

Sedangkan untuk bobot, Anda dapat mencoba meneruskan beban options objek ke metode index() (tempat Anda menentukan indeks gabungan) (setidaknya berfungsi dengan v4.0.1 luwak):

schema.index({ animal: 'text', color: 'text', pattern: 'text', size: 'text' }, {name: 'My text index', weights: {animal: 10, color: 4, pattern: 2, size: 1}});
person eagor    schedule 26.08.2014
comment
kesalahan yang dikembalikan: memerlukan tepat satu indeks teks untuk kueri $teks - person Mallen; 29.09.2014
comment
untuk menentukan indeks teks untuk beberapa bidang, Anda memerlukan indeks gabungan. Pastikan Anda mendefinisikan indeks gabungan dengan benar. - person eagor; 30.09.2014
comment
Apakah prosedur ini didokumentasikan di suatu tempat? Saya mencoba menggunakan indeks teks dengan luwak tetapi tidak berhasil. Saya telah membuat indeks gabungan, saya telah menggunakan operator $text seperti contoh Anda, tetapi hasilnya selalu berupa dokumen kosong. - person ira; 04.01.2015
comment
lihat $teks dokumen dan tutorial penelusuran teks. Apa versi luwakmu? (pencarian teks lengkap berfungsi untuk ver ›= 3.8.9) - person eagor; 04.01.2015
comment
Tautan dokumen itu untuk Mongo. Apakah ada sesuatu untuk Mongoose sendiri? - person Michael Cole; 11.06.2015
comment
Dengan luwak versi 4.0.1, opsi bobot dapat dioperasikan. - person Anthony O.; 10.09.2015
comment
@Mallen apakah Anda menemukan solusinya? - person OMGPOP; 07.12.2015
comment
Saya mencoba mengakses properti skor setelah saya mendapatkan hasilnya untuk menampilkannya di aplikasi saya, tetapi karena alasan tertentu saya menjadi tidak terdefinisi. Jika saya console.log array hasil, saya melihat properti skor di bawah setiap objek, tetapi jika saya secara khusus mencoba mengaksesnya, saya menjadi tidak terdefinisi. Adakah ide mengapa atau bagaimana melakukan ini dengan benar? Terima kasih. - person Alejandro Corredor; 15.06.2017
comment
Terima kasih ini berfungsi dengan baik untuk membuat indeks saat menggunakan luwak. Bisakah Anda memberi tahu saya cara menghapus indeks di luwak? - person Goutham; 22.06.2017

Mulai MongoDB 2.6, sebuah koleksi dapat memiliki paling banyak satu indeks teks (didokumentasikan di sini). Oleh karena itu, Anda tidak akan dapat melakukan apa yang Anda inginkan dengan versi MongoDB saat ini. Sungguh, untuk masalah pencarian teks yang rumit dengan persyaratan bobot yang berbeda tergantung pada lokasi kecocokan, Anda harus mempertimbangkan solusi pencarian teks lengkap seperti Solr atau ElasticSearch.

Sebagai solusinya di MongoDB, Anda dapat memberi token pada kolom secara manual, menyimpannya sebagai array kata kunci, dan mengindeksnya:

animal: ["The", "quick", "brown", "fox", "jump", ..., "dog"]

lalu pertanyaan seperti

db.test.find({hewan: {$in: ["coklat", "sepatu"]})

meniru pencarian teks. Ada beberapa keterbatasan dari pendekatan ini seperti pekerjaan manual yang diperlukan untuk menyiapkannya, fakta bahwa tidak akan ada stemming, misalnya, mencocokkan "bermimpi" dengan "mimpi", fakta bahwa stopwords tidak akan dihapus seperti di a indeks teks normal, dan tidak adanya mekanisme pembobotan apa pun.

person wdberkeley    schedule 24.07.2014
comment
Sebenarnya saya hanya punya satu indeks teks dengan banyak bidang. Kode pukulan adalah bagian dari .getIndexes(). Saya melakukannya dengan mongoose-text-search, saya sedang mencari versi luwak murni itu. ` { v : 1, kunci : { _fts : teks, _ftsx : 1 }, ns : public-diary-dev.diaries, nama : indeks pencarian lengkap, latar belakang : true, bobot : { tag : 1, teks : 1 , judul : 1 }, bahasa_default : bahasa inggris, bahasa_override : bahasa, textIndexVersion : 1 } ` - person Foad Nosrati Habibi; 27.07.2014

Saya menemukan artikel berikut yang mengarahkan saya ke http://code.tutsplus.com/tutorials/full-text-search-in-mongodb--cms-24835 Saya menghilangkan indeks yang dibuat di jawaban teratas menggunakan yang berikut ini

db.tablename.dropIndex({"indexname_text"})  

Saya mendapatkan daftar indeks dengan perintah ini

db.tablename.getIndexes()

Saya kemudian menggunakan yang berikut ini untuk membuat indeks

db.tablename.createIndex({"$**":"text"})

perintah berikut berfungsi di Mongoose

model.find(
    {$text: {$search: "text you are searching for"}},
    {score: {$meta: "textScore"}})
    .sort({score:{$meta:"textScore"}}
)
.exec(function(err, results) {
    `enter code here`if(!err){
    console.log('results ' + results);
}
else
{
    console.log(err);
}
});
person Gordon Deudney    schedule 14.07.2016

person    schedule
comment
Jawaban ini adalah bomnya! Saya menyia-nyiakan dua jam terakhir untuk mencoba menambahkan indeks teks ke skema saya dan hanya jawaban sederhana inilah yang saya butuhkan. Sabas! - person ecg8; 24.02.2018
comment
Ya, benar, tetapi Anda tidak dapat membuat kueri yang ramah manusia dengan menghindari penggunaan ekspresi reguler. - person Akhmedzianov Danilian; 13.05.2018
comment
Berhati-hatilah dengan hal ini, karena dapat mengakibatkan kerentanan penolakan layanan regex - person BrotherDonkey; 08.06.2020