2013-03-22 68 views
0

我有大量的文件,每一天都有效。范围可以从1周到1年。我希望能够获取在特定日期有效的所有文档。如何获得在给定日期有效的所有CouchDB文档的列表?

我该怎么做?

举个例子说,我有以下两个文件:

doc1 = { 
    // 1 year ago to today 
    start_at: "2012-03-22T00:00:00Z", 
    end_at: "2013-03-22T00:00:00Z" 
} 

doc2 = { 
    // 2 months ago to today 
    start_at: "2012-01-22T00:00:00Z", 
    end_at: "2013-03-22T00:00:00Z" 
} 

和地图功能:

(doc) -> 
    emit([doc.start_at, doc.end_at], null) 

所以对于6个月前的日期我只会得到DOC1,日期一个星期前我会得到这两份文件,并且明天的日期我将不会收到任何文件。

请注意,实际的解决方案需要下到第二个请求,并且有很多文件,所以为每个有效秒发出一个密钥的策略是不合适的。

回答

1

您可以在您的范围内每天呼叫发射,然后您可以轻松挑选出特定日期的可用文档。

function(doc) { 
    var day = new Date(doc.start), 
     end = new Date(doc.end).getTime(); 

    do { 
     emit(day); 
     day = new Date(day.getFullYear(), day.getMonth(), day.getDate() + 1); 
    } while (day.getTime() <= end); 
} 

即使你将有很多的文件,如果你离开了你的EMIT的价值部分(第二PARAM),该指数将是小,因为它也可能会被。

如果您需要更复杂,可以试用couchdb-lucene。您可以将日期字段索引为日期对象,并在1请求中使用多个字段执行范围查询。

+0

获取对于给定日期有效的所有文档可能足够小以便在客户端处理以确定哪些仍然有效。虽然平均而言,每个文档需要180个发射......我想避免为这个问题增加任何额外的技术。 – Simon 2013-03-22 22:23:00

+0

我至少会对它进行一次基准测试,看看你是否真的遇到过任何问题,我听说过一些相当大的观点。 – 2013-03-22 23:42:20

+0

也许如果你使用星期数来代替,你可以使用大约1/7的磁盘空间,也许可以用一个'_list'函数来完成过滤器。 – 2013-03-22 23:45:33

0

您可以将问题转化为位置的计算几何问题。对于二维平面中的文档[x,y]=[start_at,end_at]查询那些在日期date处有效的查询是矩形中的点列表:left=-infinity, right=datestart_at<date)和bottom=date, top=infinityend_at>date)。

不幸的是,CouchDB团队低估了计算几何的力量,并且不支持多维查询。有GeoCouch扩展,它允许你做这样的查询一样容易:

http://localhost:5984/places/_design/main/_spatial/points?bbox=0,0,180,90 

上发射的空间价值的观点:

emit({ type: "Point", coordinates: [doc.start_at, doc.end_at] }, doc); 

的问题是不同的数据类型。你得到的浮点数在[-180.0,180.0]/[-90.0,90.0]的范围内,至少需要int(UNIX时间格式)。如果GeoCouch适用于范围大于180.0的范围,并且为地理计算设计的浮点运算精度对于精度为秒的日期已足够,那么您的问题已解决:)我确信,只需很少的技巧和黑客,就可以有效地解决此问题在地理软件。如果不是GeoCouch,那么也许ElastiSearch(也支持多维查询)可以很容易地用于CouchDB及其River插件系统。

+0

我宁愿不引入其他技术。这种情况下的数据转换并不重要,因为我只需要对文档是否有效进行布尔检查。 – Simon 2013-03-23 14:26:20

相关问题