0

I import to mongodb a database, that looks like this:

{
    other values,
    "addresses" : [ 
        {
            "_id" : 
            "createdAt" : 
            "likes" : 
            "type" : 
            "route" : 
            "country" : 
            "administrative_area_level_1" : 
            "administrative_area_level_2" : 
            "locality" : 
            "postal_code" : 
            "street_number" : 
        }
    ],
    other values
}

I want to add a new property to the database and thus create this schema:

const schema = new Schema({
    addresses: [{
        route: String,
        coordinates:[{
            coordsSet: {
                type: Boolean,
                default: false
            },
            lat: String,
            lon: String
        }]
    }],
    name: String,     
});

And while I can find the record by ID for example I am unable to set coordinates to the new record after I call google API. I do it this way:

   baza.findOneAndUpdate({ "addresses._id": response.id }, {$set: {"addresses.coordinates[0].lat": response.lat}}).then((update) =>{
            res.send(update);
        })

But I am unable to do that. res.send shows that I created "coordinates": [], however I cannot set it.

I dont have this problem when I want to add those new properties outside the adresses object, so I suppose I am failing with nesting some information. What am I doing wrong?

MazMat
  • 1,904
  • 3
  • 12
  • 24
  • Wrap your `$set` in quotation marks like so, `"$set"`. Please look at [this](https://stackoverflow.com/questions/41501939/how-to-update-a-array-value-in-mongoose#41502103) question – wmash Feb 26 '18 at 09:29
  • There is no change in behaviour whatsoever – MazMat Feb 26 '18 at 09:39
  • Can you attempt to use `findByIdAndUpdate` and see if there is any difference in behaviour? – wmash Feb 26 '18 at 09:46
  • Just tried that, also no change in behaviour. I just dont understand why it works outside of addresses but not inside of them – MazMat Feb 26 '18 at 09:52
  • Can you supply what `other_values` are presented as in Mongo? So just copy the structure and omit any values that are sensitive – wmash Feb 26 '18 at 09:58

2 Answers2

1

Try this:

baza.findOneAndUpdate({ "addresses._id": response.id }, {$set:{"addresses.coordinates[0].lat": response.lat}}, { new : true }).then((update) =>{
            res.send(update);
        })

The third param '{ new : true }' means return the modified document.

Shawn He
  • 46
  • 1
  • I have no problem with returning modified document, because it's not getting modified, thats the problem. – MazMat Feb 26 '18 at 09:40
1

Google API returns lat long in float, not String

And you have specified String in the schema, That may be the reason the it is not getting stored. mongoose won't allow any data to be stored if it is not in the specified format. and They don't give in error as well.

Try

 baza.findOneAndUpdate({ "addresses._id": response.id }, {$set: {"addresses.coordinates[0].lat": response.lat.toString()}}).then((update) =>{
            res.send(update);
        })

If this does not work can you post the whole schema? With all child schemas.

Edit :- Do you already have a 0th element in coordinates key in the document? If you don't have any then $set won't work. You will have to use

$push : { coordinates : { lat :   response.lat.toString() }}

Edit This finally did the trick

as addresses itself is an array you have to push with $ operator or index

$push : { "addresses.$.coordinates" : { lat : response.lat }}
Parth Acharya
  • 545
  • 3
  • 13
  • I tried it, no change in behaviour. Also mongoose didnt have problem with setting the lat lon as string when I did it outside of the adresses object. I will try one more solution proposed above and if it doesnt work ill post whole schema but thats pretty much it what you already see. Unless I have to copy ALL properties to schema in order to make it work – MazMat Feb 26 '18 at 09:50
  • I didnt have any elements before, so I used $push. Tried with quotes and without quotes, sadly, it still doesnt make it work. I will post my whole Schema in 1 minute – MazMat Feb 26 '18 at 09:56
  • Made it work. I used `{$set: {addresses: {coordinates: {lat:response.lat }} }}}` so switched push with set after all – MazMat Feb 26 '18 at 10:00
  • Well That's strange, But whatever works for you. Although this would set lattitude of every object in the entire array. – Parth Acharya Feb 26 '18 at 10:02
  • Well, youre right it actually overwritten the rest of the address. So it still doesnt work after all, no idea why push wont work at this point – MazMat Feb 26 '18 at 10:05
  • okay wait, addresses itself is an array.. Try this $push : { "addresses.$.coordinates" : { lat : response.lat }} – Parth Acharya Feb 26 '18 at 10:09
  • Both push and set works now, instead of dollar sign i simply used 0 for now, because all arrays are single element for now. Thank you – MazMat Feb 26 '18 at 11:18