Properties instantiated as null in couchDB if not set #14

Closed
tourque3000 opened this Issue Feb 5, 2010 · 5 comments

Projects

None yet

3 participants

@tourque3000

Hi;

I have a model of a user with a first name and last name field. From what I understand of couchDB, if i set the first_name but not the last name, the document in the database should ONLY contain the first name field - However it looks like the last_name field also gets instantiated with a NULL value. Can you clarify if this is expected behaviour?

@langalex
Owner
langalex commented Feb 6, 2010

hm, to be honest i've never really thought about this. in terms of you map function it doesn't really matter if a value is null or not there at all does it? do you have any specific reason you would prefer to not have the attribute show up in the document at all?

@tourque3000

One reason would be space - you aren't cluttering up the database with NULL pointers. Also, one of the advantages of couchDB is the fact that you don't have to create a schema for your database, you just toss things in! By having to specify properties on the model and then have these propagate to the database seems to be against the spirit of couchDB. As far as the map function goes - if it is not there then it will not be displayed.

The coolest thing about couchDB is that documents can be of variable length. I am quite sure that you are aware of this, but I spent some time writing the following example I am just going to include it anyway for anyone else who might be interested.

Let me try to explain myself through example. Lets say I want to create a database that will store everyone i know including any associated addresses and other details about them. lets call this database 'contacts'. Within Contacts we can put pretty much whatever we want within it. Some of the contacts I have I know quite a bit about; others I may only know their name. In a relational database I would have to create all the fields for all the types of information I would like to store. couchDB on the other hand allows me to add fields to documents when and where i need them but doesn't clutter up the database with null pointers on documents that don't have certain associated information.

Here is what a typical person would look like in a relational database

people
first_name last_name phone address_1 address_2 pager relation
John Doolittle 555-555-5555 432 3rd st 123 5th ave NULL brother
Jason Bourne NULL NULL NULL NULL friend
Jill Haverson 555-235-5521 NULL NULL NULL friend

In couchDB, you only need to specify what you have, and can always come back later to add information. This is how the same would look like in couchDB

people
{
   "first_name": "Jon",
   "last_name": "Doolittle",
   "address": [
       "432 3rd st",
       "123 5th ave"
   ],
   "pager": null,
   "relation": "brother",
   "phone": "555-555-5555"
}
{
   "first_name": "Jason",
   "last_name": "Bourne",
   "relation": "friend"
}
{
   "first_name": "Jill",
   "last_name": "Haverson",
   "relation": "friend"
}

This is my understanding of couchDB and where the differences are between couchDB and relational databases. Does it matter if there are NULL pointers? probably not, but I feel that it does get rid of some of the flexibility of the platform if you have to explicitly define a schema in the model.

@langalex
Owner
langalex commented Feb 7, 2010

ok so i agree that it's not very beautiful to have these null attributes in the documents.

as with having to declare properties in the model: yes that enforces some kind of schema on the documents (although this is not as strongly enforced as with a relational db, as of now you can overwrite #to_hash in order to produce any kind of document you want) but at the same time it allows you to put sensible constraints on the model. e.g a user must have a login and a password.

i will happily accept a patch that gets rid of the null attributes and if you have any idea how to add a layer of schema-freeness to the models i would love to see it (btw you can already read attributes that are not declared but were still in the document that came from couchdb).

@langalex
Owner

saving nil attributes was actually added explicitly a while ago (http://github.com/langalex/couch_potato/commit/34ab327ef27edeaecebdf070fccbcf160ad78a64) - can't remember why though, will ask the author

@jweiss
Contributor
jweiss commented Mar 30, 2010

I added this explicitly because missing the attributes in the JSON broke some views (I remember the foreign lookup view for SimplyStored but I think there were more).

Further I think it breaks POLA as when I define an attribute and it is nil I expect it to be null in the JSON. nil and not defined are different things.

I disagree that this is against the CouchDB spirit. Flexible schema does not mean totally no structure. If I don't care about schema at all, I wouldn't use CouchPotato properties at all or just one called json :-) I just told CouchPotato that every user has a last name. So then I look at the JSON I expect to see lastname: null. Not having a last name attribute at all would loose meaning that I explicitly put in my CouchPotato model.

For me it is similar to Ruby hashes. There is a difference between a key with a value of nil and a non-existent key although both value lookups through the key return nil.

In you example of a contact, maybe CouchPotato properties are a bad abstraction as you don't know you attributes. So you should introspect the JOSN at runtime and decide dynamically what structure is has and not bind fixed attributes at class loading time like with CouchPotato.

P.S: Who cares about file sizes these days?

@langalex langalex closed this May 18, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment