-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Partials and Circular References
Partials are a really important concept for more than just their convenience. There is actually a lot of math and concurrency benefits to them, but we will not explore that here. Instead, we will go over how it practically impacts your life and makes things easier.
To illustrate, take the example:
var mark = gun.put({
username: "marknadal",
name: "Mark Nadal",
email: "[email protected]"
});
In most databases, if you were to then do:
mark.put({
hacker: true,
country: "USA"
});
It would completely wipe out all your data previously there and replace it with that new object. This is fundamentally bad beyond just it not being the behavior you intended, it can also cause race conditions. Which is why most other databases are centralized around one master.
But we are not like that, not only because we want a bunch of your users to simultaneously interact with data, but also because that is the pattern you expect. No need to constantly do some .update({find: 'foobar'}, {$set: {just: "my stinking location"}})
command.
Additionally, if you did want such behavior, it is much more explicit to declare .update({find: 'foobar'}, null).update({find: 'foobar'}, {some: "new object"})
. As a result, gun accepts partial updates by default and preserves your data unless you explicitly null
it out.
Partials let you work with your data without having to redownload the whole snapshot every time. Which is a common work around for dealing with cache invalidation in other databases. Even still, it is a poor one because it does not properly control for the concurrency during the latency of the expensive round trip of the data.
In conclusion, partials rock. Enjoy the freedom and flexibility of using them.
Similarly, you might be familiar with doing something like:
var mark = {
name: "Mark Nadal"
};
var cat = {
name: "Timber",
human: mark
};
mark.pet = cat;
And then somewhere down the road you attempt to JSON.stringify(mark)
and you get some nasty circular reference error. This is also silly, if the algorithm is smart enough to catch infinite recursions then it is trivial to serialize it properly. GUN does this for you, using the power of graphs. It is nothing fancy, it is the same thing that the web does - two webpages can link to each other.
Unfortunately, JSON was designed with a documented oriented structure in mind, otherwise known as a tree. This was also a fatal flaw of many NoSQL databases. Working with JSON is great for developers, since our minds easily grasp the behavior of documents. But storing data as a tree creates a nightmare of usability if and when the developer wants to do anything remotely more advanced.
GUN makes this easy:
// create mark
var mark = gun.get('marknadal').put({
name: "Mark Nadal"
})
// create the cat
var cat = gun.get('timber').put({
name: "Timber"
})
// link mark to the cat
cat.get('human').put( mark )
// link amber to mark
mark.get('pet').put( cat )
This lets us do some crazy fun inception things like:
gun.get('marknadal').get('pet').get('human').get('name').once(
(name) => console.log( "Mark's pet's human's name is "+name)
)
In conclusion, graphs rock. Enjoy the using both relational and documented structured data.