mongoosejs/mpath

set() does not create a nested structure

olastor opened this issue · 4 comments

Perhaps this is expected behaviour, but I do not understand why this does not work:

const obj = {};
mpath.set('a.b', 3, obj);
console.log(obj); // => {}

It returns an empty object {}, while I was expecting it to return { a: { b: 3 } }. Using .get() it works the other way around:

const obj = { a: { b: 3 } };
console.log(mpath.get('a.b', obj)); // => 3

@olastor Yeah, it looks like a bug because mpath is an implementation of a MongoDB-like path notation and MongoDB works as you expect.
@vkarpov15 Are there any similar bugs in mongoose?

What is the actual behavior if you do a

mpath.set('a.3.3', 3, obj);

I mean it could be
{"a": { "3": { "3": 3}}}
or
{ "a": [ undefined, undefined, [ undefined, undefined, 3]]}
or
...

@Uzlopak I think mpath should err on the side of consistency with the MongoDB server. So the first one you listed is the "correct" behavior.

MongoDB Enterprise > db.test.insertOne({})
{
	"acknowledged" : true,
	"insertedId" : ObjectId("61ea0ffcf42ebc54036f1abc")
}
MongoDB Enterprise > db.test.count()
1
MongoDB Enterprise > db.test.updateOne({}, { $set: { 'a.3.3': 3 } })
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
MongoDB Enterprise > db.test.findOne()
{
	"_id" : ObjectId("61ea0ffcf42ebc54036f1abc"),
	"a" : {
		"3" : {
			"3" : 3
		}
	}
}
MongoDB Enterprise > 

But anyway, I ran into this limitation recently with Mongoose as well. I'll open an issue to track this in Mongoose

@vkarpov15
could be solved like this...
Uzlopak@1e3b431