我需要在数据库中保留系统中所有事务的元数据(事务uuid,source,destination等)
我需要创建一个视图,计算每个目标的所有唯一来源。 例如,如果交易的src-dst夫妇是:
我想得到:
这是因为sst1和src2是针对dst1计算的(我不想两次计算src1。)
如何在Couchdb中执行此操作?
此外,有没有办法只获得具有超过X个唯一来源的目的地?
答案 0 :(得分:0)
你的问题的第一部分在CouchDB中是棘手的,它不是为了很好地处理这种关系数据。如果可能,您应该重新构建文档,以便明确存储每个目标的源列表。有了这个,您可以简单地编写一个视图来将目标映射到源计数。假设您有每个目的地的文件:
function(doc) {
emit(doc.id, doc.sources.length);
}
问题的第二部分是创建新视图并交换值的关键字,因此您可以根据每个文档的来源数量进行查询:
function(doc) {
emit(doc.sources.length, doc.id);
}
然后指定最小值的startkey
:
?startkey=5
如果无法做到这一点,您可以使用map / reduce函数为您提供所有唯一的行,但无法让它告诉您有多少行。
如果您在数据库中拥有的是源和目标对(如您所建议的那样),您可以编写这样的地图函数:
function(doc) {
emit([doc.destination, doc.source], null);
}
然后使用reduce函数来计算唯一对的数量。在这种情况下,您应该能够简单地使用内置的count
函数(如果您是新手来减少函数,我最近wrote a blog post讨论了基础知识):
_count
如果使用group=true
查询此视图,则会为每个唯一目标/源对返回一行。您可以获得特定目的地的所有配对,如下所示:
?group=true&startkey=["dst1"]&endkey=["dst1",%20{}]
此时您可以简单地计算内存中的行数。如果这不实用(例如,你有很多返回的行),你将不得不考虑编写一个列表函数来产生计数:
function() {
var count = 0;
while(getRow())
count++;
return JSON.stringify({\"count\": count});
}
然后以相同的方式调用此列表函数,对于您之前的视图:
/database/_design/designDocName/_list/listName/viewName?group=true&startkey=["dst1"]&endkey=["dst1",%20{}]
这将为您提供一个JSON对象,告诉您指定目标的唯一行数。
这可能看起来都很笨拙 - 而且确实如此。文档数据库不能很好地处理这些类型的关系,并倾向于使用非规范化文档和嵌套:
{
"_id": "dst1",
"sources": ["src1", "src2", "src3"]
}