2013-03-22 109 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

相關問題