MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Luwak - Cari teks dalam tiga bidang berdasarkan skor atau bobot

"indeks teks" dan telusuri memang kemungkinan pilihan terbaik di sini selama Anda mencari seluruh kata.

Menambahkan indeks teks ke definisi skema Anda cukup sederhana:

BookSchema.index(
    {
         "name": "text",
         "description": "text",
         "body": "text"
    },
    {
        "weights": {
            "name": 5,
            "description": 2
        }
    }
)

Ini memungkinkan Anda melakukan penelusuran sederhana dengan bobot "setel" ke bidang:

Book.find({ "$text": { "$search": "Holiday School Year" } })
    .select({ "score": { "$meta": "textScore" } })
    .sort({ "score": { "$meta": "textScore" } })
    .exec(function(err,result) {

    }
);

Di mana setiap istilah yang cocok akan dipertimbangkan terhadap bidang yang ditemukan yang memberikan bobot dan jumlah kemunculan paling banyak.

Menetapkan bobot dilampirkan ke "indeks", sehingga definisi dilakukan sekali dan tidak dapat diubah. Keterbatasan lain adalah bahwa pada "pencarian teks" tidak melihat kata-kata "sebagian". Misalnya "ci" tidak cocok dengan "Kota" atau "Warga", dan untuk hal seperti itu Anda memerlukan ekspresi reguler sebagai gantinya.

Jika Anda membutuhkan lebih banyak fleksibilitas dari itu atau umumnya harus dapat secara dinamis mengubah bobot hasil, maka Anda memerlukan sesuatu seperti kerangka kerja agregasi atau mapReduce.

Namun kerangka agregasi tidak dapat melakukan "logis" yang cocok operasi ( dapat menyaring melalui $match operator, tetapi bukan kecocokan "logis" ) dari "ekspresi reguler" dengan istilah Anda. Anda dapat bekerja dengan satu kata dan kecocokan "tepat" jika ini cocok.

Book.aggregate(
    [
        { "$match": {
            "$or": [
                { "name": /Holiday/ },
                { "description": /Holiday/ },
                { "body": /Holiday/ }
            ]
        }},
        { "$project": {
            "name": 1,
            "description": 1,
            "body": 1,
            "score": {
                "$add": [
                    { "$cond": [{ "$eq": [ "$name", "Holiday" ] },5,0 ] },
                    { "$cond": [{ "$eq": [ "$description", "Holiday" ] },2,0 ] },
                    { "$cond": [{ "$eq": [ "$body", "Holiday" ] },1,0 ] }
                ]
            }
        }},
        { "$sort": { "score": -1 } }
    ],
    function(err,results) {

    }
)

Karena pipa agregasi menggunakan struktur data untuk membuat kueri di mana Anda dapat mengubah parameter bobot pada setiap eksekusi menjadi apa pun yang Anda butuhkan saat ini.

MapReduce berbagi prinsip serupa, di mana Anda dapat memasukkan "skor" yang dihitung di bagian kunci utama yang dipancarkan sebagai elemen utama. MapReduce secara alami mengurutkan semua input yang dipancarkan oleh kunci ini sebagai pengoptimalan untuk mengumpankan ke fungsi reduksi. Namun Anda tidak dapat mengurutkan atau "membatasi" hasil seperti itu lebih lanjut.

Itu umumnya pilihan Anda untuk dilihat dan diputuskan mana yang paling sesuai dengan kasus Anda.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Konfigurasikan logging untuk driver MongoDB Java

  2. Bagaimana cara menyimpan array objek ke DB luwak hanya dengan satu panggilan?

  3. Bagaimana cara menyimpan Tanggal dan Waktu di Meteor untuk kueri rentang?

  4. Meteor:URL MongoDB unik untuk pengguna yang berbeda

  5. Bagaimana cara mendeteksi apakah serializer mongodb sudah terdaftar?