I'm pretty new to couchDB and I'm trying to wrap my mind behind the doc _id
's usage. What I read and learned so far, is that I should generate a doc _id
so I can use the B-tree for Index/Maping. Suggested are tools like Docuri or pouchdb/collate.
Let some code speak for itself:
// define a docuri route
Docuri.routes({
':type/:name/:created_at': 'list'
});
var doc = {};
doc.name = 'Testname_1';
doc.type = 'List';
doc.created_at = Math.floor(Date.now() / 1000);
doc.updated_at = Math.floor(Date.now() / 1000);
doc._id = Docuri.list(doc);
console.log(doc');
// {
// _id: "list/Testname_1/1433973431"
// created_at: 1433973431
// name: "Testname_1"
// type: "list"
// updated_at: 1433973431
// }
Next I would add some items for a list with the following doc
sturcture.
// define a docuri route
Docuri.routes({
'/:list_id/:type/:item/:created_at': 'item'
});
var doc = {};
doc.item = 'Item_1';
doc.type = 'Item';
doc.list_id = 'List/Testname_1/1433973431';
doc.created_at = Math.floor(Date.now() / 1000);
doc.updated_at = Math.floor(Date.now() / 1000);
doc._id = Docuri.item(doc);
console.log(doc');
// {
// _id: "List/Testname_1/1433973431/Item/Item_1/1433973431"
// list_id: "List/Testname_1/1433973431"
// created_at: 1433973431
// item: "Item_1"
// type: "Item"
// updated_at: 1433973431
// }
Question No.1
Is this a good structure for smaller databases?
Question No.2
(And this bugs me mostly) Let's say I would use the List _id
's like <a href="List/Testname_1/1433973431/">Testname_1</a>
. And now what if the List Name would change, should I change the List _id
's too and then change all list_id
's from the corresponding Items?
This seems pretty odd to me since I would normally not change the ID from a database entry.
But on the other hand a user would expect that the HMTL-Link corresponds to his new Listname.
Maybe someone can push me in the right direction, how to manage and use the _id
's in couchDB and pouchDB
Edit
Here are the two tutorials were I read about the UUIDs
Before deciding on using a random value as doc _id, read the section When not to use map reduce
Use domain specific document ids where possible. With CouchDB it is best practice to use meaningful ids.
http://docs.ehealthafrica.org/couchdb-best-practices/
In this example, you're getting all those "indexes" for free, each time a document is added to the database. It doesn't take up any additional space on disk compared to the randomly-generated UUIDs, and you don't have to wait for a view to get built up, nor do you have to understand the map/reduce API at all.
Of course, this system starts to get shaky when you need to search by a variety of criteria: e.g. all albums sorted by year, artists sorted by age, etc. And you can only sort strings – not numbers, booleans, arrays, or arbitrary JSON objects, like the map/reduce API supports. But for a lot of simple applications, you can get by without using the query() API at all.
Performance tip: if you're just using the randomly-generated doc IDs, then you're not only missing out on an opportunity to get a free index – you're also incurring the overhead of building an index you're never going to use. So use and abuse your doc IDs!
http://pouchdb.com/2014/05/01/secondary-indexes-have-landed-in-pouchdb.html
I ended up using the two Helper Scripts, docuri and speakingurl.
The entries in my "List" database now have a new field
slug
. First I use speakingUrl to create aslug
from the List Name provided by the User, and then use docuri to generate the_id
withslug
value.My list docs look like this:
Sort Lists by name in p/couchDB
{ startkey: 'list', endkey: 'list\uffff' }
With this setup I can use the slug field for the List URL www.foo.bar/list/my-list-name-is-test. On the destination page I use the URL slug to query the List Items with the following filter
{ startkey: 'item/' + URL_SLUG_VAR, endkey: 'item/' + URL_SLUG_VAR + '\uffff' }
My Item docs look like this:
When the User now changes the List Name value, the
slug
should stay the same and so the query for the Items should work.The downside of this solution is, when the user changes the List Name, the
slug
would NOT change and so the URL would stay the way it was created in the first place. This is IMHO not the best usability, since the user would expect that the URL to his List corresponds to the NEW List Name.I'm still thinking about to also change the corresponding Items
_id
s when the List Name changes. But this "feels" like the wrong way to go in consideration of database performance & design.If anyone comes up with a better solution or any suggestions, please post them.