Why is mongo dot notation replacing an entire subdocument?
Asked Answered
A

2

6

I've got the following doc in my db:

{
  "_id": ObjectId("ABCDEFG12345"),
  "options" : {
    "foo": "bar",
    "another": "something"
  },
  "date" : {
    "created": 1234567890,
    "updated": 0
  }
}

And I want to update options.foo and date.updated at the same time using dot notation, like so:

var mongojs = require('mongojs');

var optionName = 'foo';
var optionValue = 'baz';

var updates = {};
updates['options.' + optionName] = optionValue;
updates['date.updated'] = new Date().getTime();

db.myCollection.findAndModify({
    query : {
        _id : ObjectId('ABCDEFG12345')
    },
    update : {
        $set : updates
    },
    upsert : false,
    new : true
}, function(error, doc, result) {

    console.log(doc.options);
    console.log(doc.date);

});

And this results in:

{
  foo : 'baz',
  another : 'something'
}
{
  updated : 1234567890
}

Specifically, my pre-existing date.created field is getting clobbered even though I'm using dot notation.

Why is this only partially working? The options sub-document retains its pre-existing data (options.another), why doesn't the date sub-document retain its pre-existing data?

Astrophysics answered 24/1, 2017 at 7:40 Comment(4)
I ran the above code and got the expected output { foo: 'baz', another: 'something' } { created: 1234567890, updated: 1486112116738 } . Are you sure your data/code is as above?Amidst
100%. I must have checked it 50 times now. It makes no sense, right? I've got other modules that use the exact same technique and achieve the expected result, but not this one for some reason. Hoping to find an edge-case that someone else has run into.Astrophysics
I agree with @Amidst it works fine for me too. AJB Can you please post exact document and code steps.Garganey
It could be a bug with the mongojs library, why not try the native mongodb, for me it's been a lot more reliable than any wrapper.Religiosity
F
2

The behavior described typically happens when the object passed in the $set operator is of the form { "data" : { "updated" : 1234567890 } } rather than { "data.updated" : 1234567890 }, but I'm not familiar with dots in JavaScript enough to tell if that could be the cause on JS's side.

Also, it wouldn't explain why it happens with data and not options.

If you could print the object stored in the variable updates and that is sent to MongoDB in the update field, that would allow to tell on which side the issue is (JS or MongoDB).

Fantasist answered 3/2, 2017 at 8:42 Comment(1)
A point for the illustration of what should be happening that may help other passers-by, but dot notation should be achieving the expected result, except it's not.Astrophysics
L
1

i pass your code to a test environment and use the same library you are using. The mongojs library, for query by native ObjectId is like this mongojs.ObjectId("####") Can look the official documentation.

for the callback function in the findAndModify function, the docs parameter is an array so i navigate like an arrayenter image description here

Note: [to concatenate the string i use template literals] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)

All work fine...

Lodi answered 10/2, 2017 at 18:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.