我是CouchDB和面向文档的数据库的新手。
我一直在玩CouchDB,并且能够熟悉创建文档(使用perl)并使用Futon中的Map / Reduce函数来查询数据和创建视图。
我还想弄清楚的一件事是如何使用Futon的Map / Reduce来识别文档中的重复值。
例如,如果我有以下文件:
{
"_id": "123",
"name": "carl",
"timestamp": "2012-01-27T17:06:03Z"
}
{
"_id": "124",
"name": "carl",
"timestamp": "2012-01-27T17:07:03Z"
}
我想获得一个具有重复“名称”值的文档ID列表,这是我可以用Futon Map / Reduce做的事情吗?
结果希望实现如下:
{
"name": "carl",
"dupes": [ "123", "124" ]
}
.. ..或
{
"carl": [ "123", "124" ]
}
..这将是值,以及包含这些重复值的关联文档ID。
我尝试过Map / Reduce的一些不同的东西,但据我所知,Map函数在每个文档的基础上处理数据,而Reduce函数只允许你使用键/值来自给定的文件。
我知道我可以用perl提取我需要的数据,在那里工作魔法,并得到我想要的结果,但我现在只想用CouchDB工作,以便更好地理解它的好处/局限。 / p>
我正在考虑这样做的另一种方法是使用单个文档,如RDBMS表:
{
"_id": "names",
"rec1": {
"_id": "123",
"name": "carl",
"timestamp": "2012-01-27T17:06:03Z"
},
"rec2": {
"_id": "124",
"name": "carl",
"timestamp": "2012-01-27T17:07:03Z"
}
}
..这应该允许我按照我最初的想法使用Map / Reduce函数。但是我不确定这是否理想。
我知道我的思绪仍然停留在RDBMS的土地上,所以我上面尝试做的很多事情可能都没有必要。对此有任何见解将非常感激。
谢谢!
编辑:修复了一些示例中的JSON语法。
答案 0 :(得分:7)
如果您只想要一个唯一值列表,这非常简单。如果你想识别重复项,那就不那么容易了。
在这两种情况下,像这样的地图功能应该足够了:
function (doc) {
emit(doc.name);
}
对于reduce函数,只需输入_count
。
您的视图输出将如下所示:(基于您的2个文档)
{
"rows": [
{ "key": "carl", "value": 2 }
]
}
从那里,您将获得一个名单及其频率列表。您可以自己获取该列表并对其进行过滤,或者您可以使用"所有沙发"路由并使用_list
function执行最终过滤。
function (head, req) {
var row, duplicates = [];
while (row = getRow()) {
if (row.value > 1) {
duplicates.push(row);
}
}
send(JSON.stringify(duplicates));
}
了解_list
功能,它们非常方便且功能多样。