Di MongoDB, saya menggunakan kueri besar, bagaimana saya akan membuat indeks gabungan atau indeks tunggal, sehingga waktu respons saya meningkat

Di Proyek Saya, saya memiliki koleksi posting dan ini skemanya:

posts:{
        title:            {type: String, required: false},
        text:             {type: String, required: false},
        plainDescription: {type: String, required: false},
        isBlog:           {type: Boolean,default: false},
        type:             {type: String, required: true, default:'USER', enum:["USER","GROUP"]},
        information:{
            tags:[],
            users:[],
            groups:[],
            likes:[],
            likesCount:   {type: Number, default: 0},           
            dislikes:[],
            dislikesCount:{type: Number, default: 0},
            spams:[],
            spamsCount:   {type: Number, default: 0},
            shares:[],
            sharesCount:  {type: Number, default: 0},
            comments:[],
            commentsCount:{type: Number, default: 0},
            reply:[],
            favorite: [],
            favoriteCount:{type: Number, default: 0},
            replyCount:   {type: Number, default: 0}
        },
        authorId            : { type: String, required: true},// Can be user Id or Group Id
        authorName          : { type: String, required: false},
        isReply             : { type: Boolean, default: false},
        replyOf             : { type: String, default: "",nullable: true, references: 'posts._id'},
        isQuoteReyell       : { type: Boolean, default: false},
        quoteReyellOf       : { type: String, default: "",nullable: true, references: 'posts._id'},
        createdAt           : { type: Date, default: Date.now},
        createdBy           : { type: String, required: false, references: 'users._id'},
        creatorName         : { type: String, required: true, references: 'users.userName'},
        updatedAt           : { type: Date, required: false,default: Date.now},
        updatedBy           : { type: String, required: false, references: 'users._id'},
        updatorName         : { type: String, required: false, references: 'users.userName'},
        publishedAt         : { type: Date, required: false},
        isBlockedByAdmin    : {type:  Boolean,default: false},
        isDelete            : {type:  Boolean,default: false},
        isRss               : {type:  Boolean,default: false},
        updatedObj          : [],
        sportName           : {type: String, default: ''},
        teamObj             : []
    },

dan Sesuai kebutuhan saya, ini pertanyaannya:

[{"$match":{"$and":[{"$or":[{"$and":[{"createdBy":{"$in":["5754c557bd961f3751ddd830"]}},{"createdAt":{"$lt":"2017-10-26T06:17:32.533Z"}},{"information.shares":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"sharedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}}]},{"$and":[{"isQuoteReyell":{"$ne":true}},{"updatedObj":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"type":"reyell","updatedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}},{"isReply":false}]},{"$and":[{"information.shares":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"sharedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}}]},{"$and":[{"isReply":true},{"createdBy":{"$in":["5754c557bd961f3751ddd830"]}},{"updatedAt":{"$lt":"2017-10-26T06:17:32.533Z"}}]},{"$and":[{"updatedObj":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"type":{"$ne":"reyell"},"updatedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}}]},{"$and":[{"createdBy":{"$in":["5754c557bd961f3751ddd830"]}},{"createdAt":{"$lt":"2017-10-26T06:17:32.533Z"}},{"isBlog":false},{"information.shares":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"sharedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}}]},{"$and":[{"isQuoteReyell":{"$ne":true}},{"updatedObj":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"type":"reyell","updatedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}},{"isReply":false}]},{"information.shares":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"sharedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}},{"$and":[{"isReply":true},{"createdBy":{"$in":["5754c557bd961f3751ddd830"]}},{"updatedAt":{"$lt":"2017-10-26T06:17:32.533Z"}},{"information.shares":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"sharedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}}]},{"$and":[{"information.shares":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"sharedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}},{"updatedObj":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"type":{"$ne":"reyell"},"updatedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}}]}]},{"isBlockedByAdmin":false},{"isDelete":false}]}},{"$unwind":"$updatedObj"},{"$match":{"$or":[{"$and":[{"updatedObj.type":"reyell"},{"updatedObj.userId":{"$in":["5754c557bd961f3751ddd830"]}}]},{"$and":[{"updatedObj.type":"create"}]}]}},{"$group":{"_id":"$_id","updated":{"$last":"$updatedObj"},"post":{"$last":"$$ROOT"}}},{"$sort":{"updated.updatedAt":-1}},{"$limit":15}]

Tolong bantu saya, Untuk kolom mana saya harus membuat indeks atau indeks gabungan, sehingga dapat meningkatkan waktu respons.


person Nitesh    schedule 26.10.2017    source sumber


Jawaban (1)


Secara umum, Anda ingin menempatkan indeks pada bidang yang paling sering digunakan sebagai kriteria filter dalam kueri Anda yang paling penting/sering, dimulai dengan bidang yang paling selektif terlebih dahulu. Ada beberapa panduan tentang topik ini sebagai bagian dari dokumentasi MongoDB. Salah satu pernyataan yang menarik untuk kasus Anda mungkin adalah ini karena Anda memiliki banyak $ors:

Umumnya MongoDB hanya menggunakan satu indeks untuk memenuhi sebagian besar kueri. Namun, setiap klausa dari kueri $or mungkin menggunakan indeks yang berbeda, dan mulai dari 2.6, MongoDB dapat menggunakan perpotongan beberapa indeks.

Namun, hal terpenting di sini adalah mengukur, mengukur, mengukur, dan melihat rencana eksekusi kueri menggunakan jelaskan(). Alasannya adalah kemungkinan besar Anda akan memiliki berbagai jenis pertanyaan yang perlu didukung oleh aplikasi Anda dan Anda harus melakukan trade-off pada titik tertentu di mana Anda harus memilih antara biaya pemeliharaan indeks (misalnya tulis kunci selama pembaruan indeks & persyaratan ruang disk) dan secara teoritis solusi tercepat di mana semua bidang yang digunakan dalam satu kueri dicakup oleh satu indeks.

Seluruh topik pengindeksan itu agak kabur dan sangat bergantung pada skenario Anda:

  • Apakah data Anda banyak diperbarui dan penulisannya harus super cepat (Anda ingin indeks yang lebih sedikit/lebih kecil) atau apakah data Anda cukup stabil dengan pembacaan yang sering dan harus cepat (gunakan indeks yang lebih banyak/lebih besar)?
  • Jenis pertanyaan apa yang perlu Anda dukung? Seberapa miripkah keduanya dalam hal filter? Akankah kombinasi filter tertentu lebih mungkin terjadi dibandingkan yang lain? Kueri mana yang perlu berkinerja baik, mana yang sedikit lebih lambat?
  • Bagaimana data di kolom yang berpotensi diindeks didistribusikan?
  • dan seterusnya...

Anda tidak akan menemukan satu indeks pun yang membantu semua kueri Anda berkinerja terbaik. Dan juga, saat menambahkan lebih banyak indeks atau mengubah indeks yang sudah ada, hal ini dapat menyebabkan pengoptimal kueri berhenti menggunakan beberapa indeks untuk beberapa kueri dan memilih rencana eksekusi berbeda yang mungkin diinginkan atau tidak. Jadi ukur semua hal yang penting pada setiap perubahan pada pengindeksan atau tata letak data fisik Anda (penyiapan perangkat keras, sharding...). Terakhir, Anda harus mengukur kinerja kueri Anda secara rutin seiring bertambahnya jumlah data, kecuali jika distribusinya diperkirakan seragam.

Singkat cerita: Gunakan pendekatan berulang dan mulailah dengan menambahkan indeks (saya menyarankan untuk menambahkan indeks pada isBlockedByAdmin, isDelete dan information.shares.userId) lalu ukur kinerja kueri Anda dan kemudian sempurnakan indeks Anda berdasarkan temuan Anda (dan sekali lagi, dan lagi, ...).

person dnickless    schedule 26.10.2017