8

node js,sails js,waterline. I need to update(or push) values into the below schema after insert

I am using sailsjs with waterline and mongodb.

{
"countries": {
"states": [
{
"statename": "state",
"districts": [
{
"distname": "district",
"cities": [
{
"cityname": "Hyderabad",
"places": [
                {
                  "placename": "hitechcity"
                }
              ]

          }
        ]
      }
    ]
  }
]
}
}

I need to know how to update it i need something like this after update

{
"countries": {
"states": [
{
"statename": "state",
"districts": [
{
"distname": "district",
"cities": [
{
"cityname": "Hyderabad",

              "places": [
                {
                  "placename": "hitechcity"
                },
                {
                  "placename": "someother place"
                }
              ]

          }
        ]
      }
    ]
  }
]
}
}

please someone help me.

1
  • Mogodb's '$'-operator supports only 1 level of array nesting, so I don't think there is a solution available for your current schema. perhaps you should rethink it once more and make it less nested. Commented Aug 10, 2013 at 10:48

2 Answers 2

16

Great question! You'll want to use addToCollection():

await User.addToCollection(23, 'roles')
.members([3, 5, 6]);

Done on my phone so sorry about any typos :)

Edited Aug 7, 2018 to reflect best practices in Sails v1. More info: https://sailsjs.com/documentation/reference/waterline-orm/models/add-to-collection

Sign up to request clarification or add additional context in comments.

11 Comments

I have the same issue and I used the solution that @mikermcneil suggests. However, I ran into trouble with race conditions. Example: The query is performed two times in a row. Both findOne-functions find the same object, and both manipulate and save the original object thereby only storing the object that was changed last...
What if I have a large number of writes? given the fact that all this is async, there may be multiplt queries to add things to as array and all of them would find the object before changing and saving. In that case all the changes except the last one would be lost. There has got to be a quiery like {user.roles : {push : {whatever} }
@anissen righto- you'd have the same problem you would doing this with Mongo out of the box-- a lack of transactions. Here's Mongo's official stance on handling transactions w/ 2-phase commits. Longer term, this will find its way into Waterline in a cross-adapter way at some point down the road. The first version of the ORM had cross-adapter transaction support, but it was removed to keep things maintainable (you can find it waaaaay back in the history of the Sails repo if you're interested)
@mikermcneil User.native() would probably work fine! Thanks! I didn't know this existed.
What if these pushed values have to be unique? Does anyone know if arrays can support unique: true?
|
4

I found that with Sails I could not use mikermcneil answer. I had to go native:

Runtestunit.native(function(err, runtestunit){
     runtestunit.find({sessionID : sessionData.id_}).toArray(function(err, results) {
         if (err) return res.serverError(err);
         runtestunit.update({ _id: results[0]._id },
           { $push: { screenshots: filename } },
           function(err, screenshots) {
           if(err) sails.log.err( err)
         else sails.log.info("Item pushed")
       })
    });
});

FYI I'm querying my data by a sessionData.id_ key

1 Comment

Thanks for posting this! Would you mind expanding this to explain why you needed to use .native() to help out folks finding this answer on Google?

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.