node-rus-diff icon indicating copy to clipboard operation
node-rus-diff copied to clipboard

$rename source field invalid

Open kevinfairclough opened this issue 11 years ago • 8 comments

Array of strings, remove first element.

diff() When comparing an array of strings with another array of strings and applying the diff I'm getting; $rename source field invalid.

{'$rename': {'Category:1':'Category:0'}}

kevinfairclough avatar Dec 01 '14 15:12 kevinfairclough

Can you paste those JSON documents?

If you want, you can also add test case to https://github.com/mirek/node-rus-diff/blob/master/spec/spec-index.coffee - I'll merge it and fix quickly.

mirek avatar Dec 01 '14 15:12 mirek

It would be great to add something smart to recognise $pop, $pull, $push etc. ops for arrays. Maybe I'll do that soon.

mirek avatar Dec 01 '14 16:12 mirek

Yeah that would be brilliant, I'm hitting the null issue referenced here: https://jira.mongodb.org/browse/SERVER-1014

I will have to do a clean up of the document afterwards.

Thank you for this.

kevinfairclough avatar Dec 01 '14 16:12 kevinfairclough

I get a 403 when trying to sync change. Here is the test (which I think is correct?)

assert.deepEqual { '$unset' : {'a.0':true} }, $.diff {a:['a','b']}, {a:['b']}

kevinfairclough avatar Dec 01 '14 16:12 kevinfairclough

console.log $.diff {a:['a','b']}, {a:['b']}
{ '$rename': { 'a.1': 'a.0' } }

console.log $.apply {a:['a','b']}, { '$rename': { 'a.1': 'a.0' } }
{ a: [ 'b', null ] }

So applying rename is broken for sure.

mirek avatar Dec 01 '14 16:12 mirek

It's because of delete behaviour:

coffee> a = [ 3, 5, 7 ]
[ 3, 5, 7 ]
coffee> delete a[1]
true
coffee> a
[ 3, null, 7 ]

I'll need to spend a bit more time on it because removing elements from the array is more "dynamic", in the sense that it changes indexes for other elements (ie. foo.4 becomes foo.3 after renaming/removing foo.2 for example) - so it needs to be invoked in the right order, otherwise it could mess other modification operators.

mirek avatar Dec 01 '14 16:12 mirek

I'm not sure on the entire $rename concept here. How can producing a diff determine if something has been renamed?

kevinfairclough avatar Dec 02 '14 15:12 kevinfairclough

@kevinfairclough $rename has just been fixed, the behaviour is quite straight forward:

  • on non-existing value (value that disappeared) remember value's hash and it's key path
  • after the diff has been completed, for each entry in $set:
    • check value's hash, if it has been unset, replace this $set with $rename to stored key path for this hash

Worth noting is that values that changed to something else can't be used for $rename because MongoDB doesn't allow it, for example { a: 1 } -> { b: 1, a: 2 } can't be considered as { $rename: { a: 'b' }, $set: { a: 2 } } - MongoDB would fail with 10150 exception: Field name duplication not allowed with modifiers

It's true that $rename is not necessary to compute diff. We can make it optional with the flag.

mirek avatar Dec 03 '14 18:12 mirek