Indexing 如何创建和维护couchDB/pcouchDB doc#u id';s
我是couchDB的新手,我正试图用Indexing 如何创建和维护couchDB/pcouchDB doc#u id';s,indexing,couchdb,pouchdb,Indexing,Couchdb,Pouchdb,我是couchDB的新手,我正试图用doc\u id的用法来表达我的想法。到目前为止,我读到并学到的是,我应该生成一个doc\u id,这样我就可以使用B-树进行索引/映射。建议使用的工具有Docuri或backdb/collate。 让一些代码自己说话: // define a docuri route Docuri.routes({ ':type/:name/:created_at': 'list' }); var doc = {};
doc\u id
的用法来表达我的想法。到目前为止,我读到并学到的是,我应该生成一个doc\u id
,这样我就可以使用B-树进行索引/映射。建议使用的工具有Docuri或backdb/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
// }
接下来,我将为具有以下结构的列表添加一些项
// 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
// }
问题1
对于较小的数据库来说,这种结构好吗
问题2
(这让我非常恼火)假设我会使用列表\u id
,就像
。现在,如果列表名称会更改,我是否也应该更改列表的\u id
,然后更改相应项目中的所有列表id
这对我来说似乎很奇怪,因为我通常不会更改数据库条目的ID
但另一方面,用户希望HMTL链接对应于他的新列表名
也许有人能把我推向正确的方向,如何管理和使用couchDB和PockDB中的\u id
编辑
以下是我读到的关于UUID的两个教程
在决定使用随机值作为doc\u id之前,请阅读“何时不使用map reduce”一节
尽可能使用特定于域的文档ID。使用CouchDB时,最好使用有意义的ID
在本例中,每次将文档添加到数据库时,您都可以免费获得所有这些“索引”。与随机生成的UUID相比,它不会占用磁盘上的任何额外空间,而且您不必等待视图建立,也不必理解map/reduce API
当然,当您需要根据各种条件进行搜索时,该系统开始变得不稳定:例如,所有专辑按年份排序,艺术家按年龄排序,等等。您只能对字符串进行排序,而不能对数字、布尔值、数组或任意JSON对象进行排序,如map/reduce API支持。但是对于许多简单的应用程序,根本不需要使用query()API就可以了
性能提示:如果您只是使用随机生成的文档ID,那么您不仅错过了获取免费索引的机会,还将导致构建一个永远不会使用的索引的开销。因此,请使用和滥用您的文档ID
Docuri是一个有趣的想法,我完全支持CouchDB技巧和类似的“黑客”,但请不要被它误导。这是一个骗局,有点像“黑客” 我基本上只有几个文档ID的策略/习惯:
- 它们是完全随机和无意义的(对于应用程序代码而言),尽管我经常在它们前面加上类型前缀,严格地说只是为了调试方便-任何需要知道文档类型的代码都是从
或类似字段获得的,而不是从doc.type
获得的。因此,我可能会将一个文档称为“photo-1qr333qew3qadeiof”,这样我就可以在web日志或其他内容中注意到它,但应用程序逻辑不会根据id假设任何内容doc.\u id
- 有时我需要确保相关文档的唯一性,例如,“用户”文档可能需要一个(或至少不超过)相关的“概要文件”文档。或者,一个更好的例子,也许我想确保一个特定的交易只发生一次:避免重复购买或其他事情。因此,我获取一个用户id和内容id的“元组”,并通过
识别购买记录。然后,如果这个特定的组合意外地再次发生,我将得到一个409*,因为这个确定性派生的id'txn-'+散列(username+song.\u id)
- 更不常见的是,我有时会为某个应用程序制作特殊的ID(比如一个名为“共享配置”或“我的应用程序全局计数器”之类的文档),这样它就可以在有限的情况下出于特定目的直接访问它们
\u all\u docs
使用/滥用“主”索引,即数据库本身,作为优化/技巧/黑客,但这不是正常做法。)
[*在Cloudant和CouchDB 2.0下,正确处理最后一个案例更为复杂,因为这是一个不同的主题。]我最终使用了两个助手脚本,并且 我的“列表”数据库中的条目现在有一个新字段
slug
。
首先,我使用speakingUrl从用户提供的列表名创建一个slug
,然后使用docuri生成带有slug
值的\u id
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"
}
}
]
[
{
"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"
}
}
]
在p/couchDB{startkey:'list',endkey:'list\uffff'}中按名称对列表进行排序
通过此设置,我可以使用列表URL的slug字段www.foo.bar/List/我的列表名为test。在目标页面上,我使用URL slug通过以下过滤器查询列表项
{startkey:'item/'+URL\u SLUG\u VAR,endkey:'item/'+URL\u SLUG\u VAR+'\uffff'}
我的项目文档如下所示:
[
{
"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"
}
}
]
[
{
"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
不会更改