2014-06-21 87 views
4

我有一個地圖縮小的視圖設置。眼下這段代碼的偉大工程:couchdb地圖/減少按日期過濾多個按鍵

function(doc) { 
    if (doc.type == 'test'){ 
     if(doc.trash != 1){ 
       for (var id in doc.items) { 
       emit([id,doc.items[id].name], 1); 
      } 
     } 
    } 
} 

function(keys,prices){ 
    return (keys, sum(prices)); 
} 

我獲得回報,並使用該組參數時,它凝聚一切就好了。

我的問題/問題,我想添加第三個鍵....日期,所以我可能只會減少某些日期的記錄。因此,例如:

function(doc) { 
    if (doc.type == 'test'){ 
     if(doc.trash != 1){ 
       for (var id in doc.items) { 
       emit([date,id,doc.items[id].name], 1); 
      } 
     } 
    } 
} 

我的問題是,由於日期是在數組的開始,按日期減少羣體,ID等。我知道我用group_level說只是把該數組中的第一個鍵或前2個鍵,但這並不能幫助,因爲afaik,group_level在數組中從左到右。我可以把日期放在發射數組的末尾,但這也沒有幫助,因爲我需要在我的startkey和endkey的開頭搜索值。

下面是數據輸出的例子:

{"key":["2012-03-13","356752b8a5f6871f3","Apple"],"value":1}, 
{"key":["2012-03-20","123752b8a76986857","Pear"],"value":1}, 
{"key":["2012-04-12","3013531de05871194","Grapefruit"],"value":1}, 
{"key":["2012-04-12","356752b8a5f6871f3","Apple"],"value":1}, 

我想在一行中添加APPLE起來,在這裏它是由日第一加起來蘋果。如果我刪除DATE作爲數組中的第一個鍵,但我無法按日期範圍進行搜索,所以我能夠成功將所有蘋果加起來。

有關如何完成此任何想法?

回答

5

如果我正確理解你想做什麼,那麼你會想把日期作爲你的數組的第一個元素,並使用group_level以及start_key和end_key。

例如, startkey=[1, "someid"] endkey=[1,"someid",{}] group_level=2

會從第1天(顯然選擇你自己的格式)中得到你所有的項目,ID爲「someid」和任何名稱。看起來很有趣的是,你放棄了ID之前的名字,並且沒有關於你實際要完成什麼的更多信息,很難建議你的通用數據模型。如果ID是一個「類型」ID,這意味着許多項目共享相同的ID,那麼這是有道理的。如果ID是唯一的每個物品ID,則它不會。在這種情況下,你會希望ID之前發出「名」 ...

編輯1

根據您的意見,做日期的範圍你這樣做:

startkey=[1] endkey=[5,{}] group_level=2

您將得到從日期1到日期5的所有內容,按id分組即ie。​​,oranges等。我在一個非常大規模的生產應用中使用這種精確的技術。我實際上將日期格式化爲格式爲yyyymmdd的易讀的整數,因此20140624將排在最前面。如果我想一切從本月開始到現在我的組ID組合,我稱之爲

startkey=[20140601] endkey=[20140624,{}] group_level=2

它完美而據我可以告訴大家,就是你找什麼做的。我還有第三個關鍵層「細節」,它允許我爲需要它的項目提供更深層次的分組。然後我可以叫

startkey=[20140601, "someid"] endkey=[20140624, "someid",{}] group_level=3

鑽取到的詳細程度特定ID,或者只是使用以前的查詢與group_level=3如果我想每一個ID的細節。我確信你可以完成這項工作 - 我已經使用所描述的技術在生產應用程序中解決了這個確切的問題。

編輯2

如果你想組不分日期的所有蘋果,那麼你就需要讓蘋果成爲關鍵中的第一個元素。然後,您可以使用group_level=1和蘋果在日期範圍內使用group_level=2,將查看結果中的所有蘋果始終作爲單行顯示。這裏的區別在於,您只能一次對單個項目類型執行group_level=2查詢。如果你想要兩全其美,你不幸的只需要製作2個視圖。這就是關鍵訂購的工作方式......如果您需要兩種查詢類型的快速響應時間,日期範圍內的所有項目類型以及未按日期分組的所有項目,我相信2個視圖是實現那。

注意

另一個要注意的是你的降低作用。只要可能,它就是高度建議您使用內置的減少功能。它們是用erlang實現的,並且與定製的javascript縮減函數相比,它們是高度優化的。

在你的情況下,只需更換您減少功能與此

_sum

容易哎?

如果您發佈有關您的應用程序,數據模型等的更多信息,那麼我很樂意爲您的數據庫設計提供更多幫助。

+1

主要問題是我需要按日期範圍進行搜索。我無法過濾id,或名稱或任何其他字段,因爲我想在特定日期內返回所有記錄。我的問題是,如果我把date作爲開始和結束鍵中的第一個參數,它會導致一個問題。爲什麼?因爲然後映射/減少分組和減少日期(不好)。我需要它通過ID分組。例如。我有一份水果名單......蘋果,葡萄柚,梨。水果每天都要多次購買。我想過濾一個日期範圍,並在給定的一天中獲取蘋果總數等。 +++ _sum建議 – Matt

+0

更新了我的答案。我在生產應用程序中完成了這件事,我們每天都會使用它來進行分析。我確定它確實有效。希望這可以幫助。 – wallacer

+0

我想我說ID是有點誤導。這裏的id不是唯一的,而是使用單詞類型。我的問題是,當你使用group和reduce時,是不是按DATE分組,然後按Type?例如,我有這個:emit([doc.ss_date,ss_type,doc.ss.name],1);減少不是首先按日期減少嗎?所以它只能說明Jun 25上的所有蘋果?而不是日期範圍內的所有蘋果?我想搜索說一週的價值記錄,並獲得一個範圍內的所有蘋果的總數。組2/3從數組中的第一個鍵(日期)開始,而不是reduce中的第二個鍵。 – Matt