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

Periksa Apakah bidang ada dalam sub-dokumen dari Array

Anda pada dasarnya ingin $elemMatch dan $exists operator, karena ini akan memeriksa setiap elemen untuk melihat apakah kondisi "bidang tidak ada" benar untuk elemen apa pun:

Model.find({
  "line_items": {
      "$elemMatch": { "review_request_sent": { "$exists": false } }
  }
},function(err,docs) {

});

Itu mengembalikan dokumen kedua hanya karena bidang tidak ada di salah satu sub-dokumen array:

{
        "id" : 2,
        "line_items" : [
                {
                        "id" : 1,
                        "review_request_sent" : false
                },
                {
                        "id" : 39
                }
        ]
}

Perhatikan bahwa "berbeda" dari formulir ini:

Model.find({
  "line_items.review_request_sent": { "$exists": false } 
},function(err,docs) {

})

Di mana yang ditanyakan apakah "semua" elemen array tidak mengandung bidang ini, yang tidak benar ketika dokumen memiliki setidaknya satu elemen yang memiliki bidang tersebut. Jadi $eleMatch membuat kondisi diuji terhadap elemen larik "setiap", dan dengan demikian Anda mendapatkan respons yang benar.

Jika Anda ingin memperbarui data ini sehingga elemen larik apa pun yang ditemukan yang tidak berisi bidang ini akan menerima bidang tersebut dengan nilai false ( mungkin ), maka Anda bahkan bisa menulis pernyataan seperti ini:

    Model.aggregate(
      [
        { "$match": { 
          "line_items": {
            "$elemMatch": { "review_request_sent": { "$exists": false } }
          } 
        }},
        { "$project": {
          "line_items": {
            "$setDifference": [
              {"$map": {
                "input": "$line_items",
                "as": "item",
                "in": {
                  "$cond": [
                    { "$eq": [ 
                      { "$ifNull": [ "$$item.review_request_sent", null ] },
                      null
                    ]},
                    "$$item.id",
                    false
                  ]
                }
              }},
              [false]
            ]
          }
        }}
    ],
    function(err,docs) {
      if (err) throw err;
      async.each(
        docs,
        function(doc,callback) {
          async.each(
            doc.line_items,
            function(item,callback) {
              Model.update(
                { "_id": doc._id, "line_items.id": item },
                { "$set": { "line_items.$.review_request_sent": false } },
                callback
              );
            },
            callback
          );
        },
        function(err) {
          if (err) throw err;
          // done
        }
      );
    }
  );

Dimana .aggregate() result tidak hanya cocok dengan dokumen, tetapi menyaring konten dari larik di mana bidang tidak ada, sehingga hanya mengembalikan "id" dari sub-dokumen tertentu.

Kemudian loop .update() pernyataan cocok dengan setiap elemen larik yang ditemukan di setiap dokumen dan menambahkan bidang yang hilang dengan nilai pada posisi yang cocok.

Dengan cara itu Anda akan memiliki bidang yang ada di semua sub-dokumen dari setiap dokumen yang sebelumnya tidak ada.

Jika Anda ingin melakukan hal seperti itu, sebaiknya ubah skema Anda untuk memastikan bidang juga selalu ada:

{id: Number,
  line_items: [{ 
    id: String,
    quantity: Number,
    review_request_sent: { type: Boolean, default: false }
  }],
  total_price: String,
  name: String,
  order_number: Number
}

Jadi pada saat Anda menambahkan item baru ke array dalam kode Anda, elemen tersebut akan selalu ada dengan nilai defaultnya jika tidak ditetapkan secara eksplisit. Dan mungkin merupakan ide yang baik untuk melakukannya, serta menyetel required di bidang lain yang selalu Anda inginkan, seperti "id".



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Luwak selalu mengembalikan array kosong NodeJS

  2. Mengapa konektor Spark Mongo tidak menekan filter?

  3. Apakah saya perlu membersihkan input pengguna sebelum memasukkan MongoDB (kombo MongoDB + Node js)

  4. Penyortiran MongoDB pada anak-anak

  5. Menemukan celah dalam aliran acara besar?