我对couchDB很新,我试图将我的想法包含在doc _id
的用法之后。到目前为止我读到和学到的是,我应该生成一个doc _id
,这样我就可以使用B树进行索引/映射。建议使用 Docuri 或 pouchdb / collate 等工具。
让一些代码说明一切:
// 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
// }
接下来,我将为列表添加一些项目,其中包含以下doc
结构。
// 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
// }
对于较小的数据库,这是一个很好的结构吗?
(这主要是我的错误)让我说我会像_id
一样使用列表<a href="List/Testname_1/1433973431/">Testname_1</a>
。现在,如果列表名称会发生变化,我是否应该更改列表_id
,然后从相应的项目中更改所有list_id
?
这对我来说似乎很奇怪,因为我通常不会更改数据库条目中的ID。
但另一方面,用户会期望HMTL-Link对应于他的新Listname。
也许有人可以推动我朝着正确的方向前进,如何管理和使用couchDB和pouchDB中的_id
修改
以下是我阅读的有关UUID的两个教程
在决定使用随机值作为doc _id之前,请阅读“何时不使用map reduce
”一节尽可能使用特定于域的文档ID。使用CouchDB时,最好使用有意义的ID。
http://docs.ehealthafrica.org/couchdb-best-practices/
在这个例子中,每次将文档添加到数据库时,您都可以免费获得所有这些“索引”。与随机生成的UUID相比,它不占用磁盘上的任何额外空间,并且您不必等待视图构建,也不必理解map / reduce API。< / p>
当然,当您需要按照各种标准进行搜索时,此系统开始变得不稳定:例如按年份排序的所有专辑,按年龄排序的艺术家等。您只能对字符串进行排序 - 而不是数字,布尔值,数组或任意JSON对象,如map / reduce API支持。但对于许多简单的应用程序,您可以完全不使用query()API。
性能提示:如果您只是使用随机生成的文档ID,那么您不仅错过了获得免费索引的机会 - 您还需要承担建立索引的开销永远不会用。因此,请使用和滥用您的文档ID!
http://pouchdb.com/2014/05/01/secondary-indexes-have-landed-in-pouchdb.html
答案 0 :(得分:1)
我最终使用了两个助手脚本,docuri和speakingurl。
我的“列表”数据库中的条目现在有一个新字段slug
。
首先,我使用 speakingUrl 从用户提供的列表名称创建slug
,然后使用 docuri 生成_id
slug
1}}值。
docUri.routes({ ':type/:slug/:created_at': 'list' });
var slug = speakingUrl('My List Name is test');
var listObj = {};
listObj.name = 'My List Name is test';
listObj.type = 'list';
listObj.created_at = Math.floor(Date.now() / 1000);
listObj.updated_at = Math.floor(Date.now() / 1000);
listObj.slug = slug;
listObj._id = docuri.list( listObj );
我的列表文档如下所示:
[
{
"id": "list/my-list-name-is-test/1436098113",
"key": "list/my-list-name-is-test/1436098113",
"value": {
"rev": "1-d96c34ce1732e3e8088c4fa9d6e54c14"
},
"doc": {
"name": "My List Name is test",
"type": "list",
"created_at": 1436098113,
"updated_at": 1436098113,
"slug": "my-list-name-is-test",
"_id": "list/my-list-name-is-test/1436098113",
"_rev": "1-d96c34ce1732e3e8088c4fa9d6e54c14"
}
}
]
按名称在p / couchDB { startkey: 'list', endkey: 'list\uffff' }
通过此设置,我可以使用列表URL www.foo.bar/list/my-list-name-is-test 的slug字段。在目标页面上,我使用URL slug查询具有以下过滤器的列表项
{ startkey: 'item/' + URL_SLUG_VAR, endkey: 'item/' + URL_SLUG_VAR + '\uffff' }
我的项目文档如下所示:
[
{
"id": "item/my-list-name-is-test/This is the item Title/1436098113",
"key": "item/my-list-name-is-test/This is the item Title/1436098113",
"value": {
"rev": "1-c023db010d075d6a9129288b0649554d"
},
"doc": {
"Title": "This is the item Title",
"type": "item",
"created_at": 1436098113,
"updated_at": 1436098113,
"slug": "this-is-the-item-title",
"_id": "item/my-list-name-is-test/This is the item Title/1436098113",
"_rev": "1-c023db010d075d6a9129288b0649554d"
}
}
]
当用户现在更改列表名称值时,slug
应该保持不变,因此对项目的查询应该有效。
此解决方案的缺点是,当用户更改列表名称时,slug
不会更改,因此URL将保持其首先创建的方式。
这是恕我直言不是最好的可用性,因为用户希望他的列表的URL对应于新的列表名称。
当列表名称更改时,我仍在考虑更改相应的项目_id
。但这种“感觉”似乎是考虑到数据库性能的错误方式。设计。
如果有人想出更好的解决方案或任何建议,请发布。
答案 1 :(得分:0)
Docuri是一个有趣的想法,我全都是CouchDB技巧和&#34; hacks&#34;像这样,但请不要被它误导。这是一个技巧,它是一个&#34; hack&#34;。
我基本上只有一些政策/习惯与文件ID:
doc.type
的{{1}}或类似字段 。所以我可以打电话给#34; photo-1qr333qew3qadeiof&#34;只是这样我可以在网络日志或其他东西中注意到它,但是应用程序逻辑不假设任何基于id的内容。doc._id
标识购买记录。然后,如果特定组合意外再次发生,我将获得409 *因为确定性派生的id。但重点是,默认情况下,除非你有充分的理由不这样做,否则你应该为你的文档使用某种UUID。 CouchDB仅在文档级别提供原子性这一事实意味着您可能会在文档ID中添加更多含义(如第二种情况),并且还可以看到像Docuri这样的技巧,使用id来优化&#34;优化&# 34;在某些情况下,但首先要将它们视为一种无意义但又独特的&#34;字符串。
您通常使用视图根据文档中的 来处理有意义的[二级]索引。 (是的,再次,您可以在特殊情况下使用/滥用&#34;主要&#34;索引即数据库本身'txn-'+hash(username + song._id)
作为优化/技巧/黑客,但这不会是正常的练习。)
[*由于its totally broken quorum handling而在Cloudant和CouchDB 2.0下正确处理最后一个案例更为复杂,但这是一个不同的主题。]