0

I'm a novice with mongodb so please excuse me if the question is a little basic. I have a mongo collection with a relatively complex document structure. The documents contain sub documents and arrays. I need to add additional data to some of the documents in this collection. A cut down version of the document is:

    "date" : ISODate("2018-08-07T08:00:00.000+0000"), 
    .
    . <<-- Other fields
    .
    "basket" : 
   [
     {
            "assetId" : NumberInt(639), 
            "securityId" : NumberInt(12470), 
            .
            . <<-- Other fields
            .
            "exGroup" : [
                . << -- Fields......
                .
                . << -- New Data will go here
            ]
     }
     .
     . << More elements

   ]

The following (abridged) aggregation query finds the documents that need modifying:

   { 
        "$match" : {
            "date" : {
                "$gte" : ISODate("2018-08-07T00:00:00.000+0000"), 
                "$lt" : ISODate("2018-08-08T00:00:00.000+0000")
            }
        }
    }, 
    { 
        "$unwind" : {
            "path" : "$basket"
        }
    }, 
    { 
        "$unwind" : {
            "path" : "$basket.exGroup"
        }
    }, 
    { 
        "$project" : {
            "_id" : 1.0, 
            "date" : 1.0, 
            "assetId" : "$basket.assetId", 
            "securityId" : "$basket.securityId", 
            "exGroup" : "$basket.exGroup"
        }
    }, 
    { 
        "$unwind" : {
            "path" : "$exGroup"
        }
    }, 
    { 
        "$match" : {
            "exGroup.order" : {
                "$exists" : true
            }
        }
    }

For each document returned by the mongo query I need to (in python) retrieve a set of additional data from a SQL database and then append this data to the original mongo document as shown above. The set of new fields will be the same, the data will be different. What is not clear to me is how, once I have the data I go about updating the array values.

Could somebody give me a pointer?

4
  • Can you update the question to show the response from the aggregate query ? Show us the actual document before and expected document after update. If you need to update an array element you have to make use of positional operator Commented Aug 9, 2018 at 14:32
  • Added a little more information. Hopefully its clearer Commented Aug 9, 2018 at 14:58
  • Thank you!. If I understand your aggregation query correctly you can replace your aggregation query with db.colname.update( {"date":{ "$gte" : ISODate("2018-08-07T00:00:00.000+0000"), "$lt" : ISODate("2018-08-08T00:00:00.000+0000")}}, { $set: { "basket.$[].exGroup.$[group]": new data} },, { arrayFilters: [ { "group.order" : { "$exists" : true } } } ) in 3.6 Commented Aug 9, 2018 at 15:02
  • Could you do me a favour and add this as an answer? I'm not sure how you are correctly indexing into the basket array Commented Aug 9, 2018 at 15:14

1 Answer 1

0

Try this, it works for me!

mySchema.aggregate([
   //your aggregation code
],function(err, docList){
  //for each doc in docList
  async.each(docList, function(doc, callback){
    query = {$and:[{idField:doc.idField},{"myArray.ArrayId":doc.myArray.ArrayId}]}
    //Update or create field in array
    update = {$set:"myArray.$.FieldNameToCreateOrUpdate":value}}
    projection = {field1:1, field2:1, field3:1}
    mySchema.findOneAndUpdate(query, update, projection, function(err, done){
        if(err){callback(err,null)}
        callback(null,'done')
    })
  ,function(err){
    //code if error
    //code if no error
  }
})
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your reply but I don't think I can use this approach. I need to retrieve the data for each element I update from a SQL database so I need to be able to issue and update on the array element in the document. What is not clear to me is how to do that?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.