CouchDB中唯一键的唯一值

时间:2014-10-14 08:40:37

标签: couchdb unique

我需要在数据库中保留系统中所有事务的元数据(事务uuid​​,source,destination等)

我需要创建一个视图,计算每个目标的所有唯一来源。 例如,如果交易的src-dst夫妇是:

  • dst1,src1
  • dst1,src1
  • dst1,src2
  • dst2,src3

我想得到:

  • dst1, 2
  • dst2,1

这是因为sst1和src2是针对dst1计算的(我不想两次计算src1。)

如何在Couchdb中执行此操作?

此外,有没有办法只获得具有超过X个唯一来源的目的地?

1 个答案:

答案 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"]
}