JSON API: operations do not update SubDoc @paths #108

wmertens opened this Issue Jun 19, 2012 · 8 comments

5 participants


Suppose you make a JSON doc that looks like this:

doc = { t: [ {id: 0}, {id: 1}, {id: 2} ] }

If you want to work with the object with id: 1 then you'd use subdoc1 = doc.at(["t", 1]). This is great, but it's not a true reference, as follows:

When you then perform an operation which alters the path to the SubDoc, the SubDoc will no longer refer to the same object. E.g. if you doc.at(t).move(0,2) then the doc becomes

doc = { t: [ {id: 1}, {id: 2}, {id: 0} ] }

and your subdoc1 will suddenly be referring to the object with id: 2.

The reason is that the path is stored when the SubDoc gets created and not updated by operations. This will manifest a lot when using arrays.

This becomes a problem if you have longstanding SubDoc references, like when you're binding textareas to SubDocs, and then do inserts etc.

I can think of these options to handle it:

  1. Declare this behavior as part of the API. So when you do an operation that changes the document layout, all SubDocs that are impacted by the change should no longer be used.
  2. Have all SubDocs listening to changes along their path and update their @path on operations.
  3. Augment each element of the JSON doc with the SubDoc prototype, perhaps on demand when you return it with at(). Then you can work with the elements directly. You won't be able to find your parent then though.



A MongoDB query would identify the child object by an immutable unique identifier, if one is available:

doc.at("t: {$elemMatch: {id:1}}");

So I would add a 4th option to handle it:
4. Revise the doc.at notation to allow an array element to be referenced by an element's values.


@drauschenbach, wouldn't that mean a database lookup on every reference? From the client side? I'm confused.


It's just an example of a notation to specify a JSON object by id, from within an array.


Oh ok - but then you'd need to add unique ids to every part of the JSON object, no?


I like option 2.


I think this is resolved now, correct?


I hope so. It should be part of issue #239

@josephg josephg closed this Sep 3, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment