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

Menggunakan operator $slice untuk mendapatkan elemen terakhir dari array

Seperti yang Anda ketahui sekarang, $slice hanya digunakan dalam proyeksi untuk membatasi elemen array yang dikembalikan dalam hasil. Jadi, Anda akan terjebak dalam memproses daftar secara terprogram dengan hasil dari find().

Pendekatan yang lebih baik adalah menggunakan agregat. Tapi pertama-tama mari kita pertimbangkan bagaimana $slice digunakan:

> db.collection.find({},{ relevancy: {$slice: -1} })
{ "_id" : ObjectId("530824b95f44eac1068b45c0"), "relevancy" : [  "Y" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c2"), "relevancy" : [  "Y" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c3"), "relevancy" : [  "N" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c4"), "relevancy" : [  "Y" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c6"), "relevancy" : [  "N" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c7"), "relevancy" : [  "N" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c8"), "relevancy" : [  "N" ] }

Jadi Anda mendapatkan elemen array terakhir, tetapi Anda terjebak dengan mengulang hasil karena Anda tidak dapat mencocokkan nilai elemen terakhir. Anda mungkin juga baru saja melakukan ini dalam kode.

Sekarang mari kita lihat agregat :

db.collection.aggregate([
    // Match things so we get rid of the documents that will never match, but it will
    // still keep some of course since they are arrays, that *may* contain "N"
    { "$match": { "relevancy": "Y" } },

    // De-normalizes the array
    { "$unwind": "$relevancy" },

    // The order of the array is retained, so just look for the $last by _id
    { "$group": { "_id": "$_id", "relevancy": { "$last": "$relevancy" } }},

    // Match only the records with the results you want
    { "$match": { "relevancy": "Y" }},

    // Oh, and maintain the original _id order [ funny thing about $last ]
    { "$sort": { "_id": 1 } }
])

Meskipun ini akan menjadi penggunaan agregat() pertama Anda, saya mendorong Anda untuk mempelajarinya . Ini mungkin alat pemecahan masalah Anda yang paling berguna. Tentu saja bagi saya. Masukkan setiap langkah sekali sekaligus jika Anda sedang belajar.

Juga tidak yakin pada formulir dokumen Anda, semua 1: { ... } notasi sub-dokumen tampaknya merupakan kesalahan tetapi Anda harus menghapusnya atau menyesuaikan kode di atas untuk referensi "1.relevancy" sebagai gantinya. Saya harap dokumen Anda benar-benar terlihat seperti ini:

{ "relevancy" : [  "Y" ] , "_id" : ObjectId("530824b95f44eac1068b45c0") }
{ "relevancy" : [  "Y",  "Y" ] , "_id" : ObjectId("530824b95f44eac1068b45c2") }
{ "relevancy" : [  "N" ], "_id" : ObjectId("530824b95f44eac1068b45c3") }
{ "relevancy" : [  "Y",  "Y" ], "_id" : ObjectId("530824b95f44eac1068b45c4") }
{ "relevancy" : [  "Y",  "N" ], "_id" : ObjectId("530824b95f44eac1068b45c6") }
{ "relevancy" : [  "N" ], "_id" : ObjectId("530824b95f44eac1068b45c7") }
{ "relevancy" : [  "Y",  "N" ], "_id" : ObjectId("530824b95f44eac1068b45c8") }

MongoDB 3.2.x dan lebih tinggi

Tentu saja MongoDB 3.2 memperkenalkan operator "agregasi" untuk $slice dan $arrayElemAt yang lebih baik lagi operator yang menghilangkan kebutuhan akan $unwind dan $group pengolahan. Setelah $match initial awal kueri Anda baru saja membuat "kecocokan logis" dengan $redact :

db.collection.aggregate([
    { "$match": { "relevancy": "Y" } },
    { "$redact": {
        "$cond": {
            "if": { "$eq": [{ "$arrayElemAt": [ "$relevancy", -1 ], "Y" ] },
            "then": "$$KEEP",
            "else": "$$PRUNE"
        }
    }}   
])

Itu akan melakukan pemeriksaan pada elemen terakhir dari array ketika memutuskan apakah akan $$KEEP atau $$PRUNE dokumen dari hasil yang dikembalikan.

Jika Anda masih menginginkan "proyeksi" maka Anda sebenarnya dapat menambahkan $slice :

db.collection.aggregate([
    { "$match": { "relevancy": "Y" } },
    { "$redact": {
        "$cond": {
            "if": { "$eq": [{ "$arrayElemAt": [ "$relevancy", -1 ], "Y" ] },
            "then": "$$KEEP",
            "else": "$$PRUNE"
        }
    }},
    { "$project": { "relevancy": { "$slice": [ "$relevancy", -1 ] } } }
])

Atau pendekatan alternatif dari:

db.collection.aggregate([
    { "$match": { "relevancy": "Y" } },
    { "$project": { "relevancy": { "$slice": [ "$relevancy", -1 ] } } },
    { "$match": { "relevancy": "Y" } }
])

Tetapi mungkin lebih murah untuk melakukan $redact pertama dan "kemudian" lakukan pembentukan ulang di `$project.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Mendapatkan agregasi yang berbeda dari bidang array di seluruh indeks

  2. Temukan url duplikat di mongodb

  3. MongoDB:Apakah mungkin membuat kueri case-insensitive?

  4. Apa bidang __v di luwak

  5. Grup dan sortir Mongodb