2011-08-24 86 views
3

我目前正在嘗試按三個值進行排序。但是,讓我們開始與文檔結構:CouchDB通過三個索引鍵查詢和過濾

{ 
    _id: "DOCIDGOESHERE01", 
    type: "MESSAGE", 
    date: "2011-08-24 06:49:02", 
    author: "USERIDGOESHERE01", 
    receiver: ["USERIDGOESHERE02", "USERIDGOESHERE03"], 
    message: "ok let's do this" 
} 

主要目標是要查詢的CouchDB的消息選定用戶發送到一個特定的用戶和日期排序。一些消息沒有任何接收器,表明它們是公開的並且可以被任何人閱讀。

地圖功能我目前使用的是這樣的:

function map(doc) { 
    if(doc.receiver.lenth==0) 
     emit([doc.date, null, doc.author], doc._id); 
    else for(var idx in doc.receiver) 
     emit([doc.date, doc.receiver[idx], doc.author], doc._id); 
} 

當查詢CouchDB的HTTP接口我tryed請求像

HTTP GET xxx/messages?key=[{}, "USERIDGOESHERE02", {}] 

HTTP POST xxx/messages 
{ 
    keys: [ 
     [{}, "USERIDGOESHERE02", "USERIDGOESHERE01"], 
     [{}, "USERIDGOESHERE02", "USERIDGOESHERE03"], 
     [{}, "USERIDGOESHERE02", "USERIDGOESHERE04"], 
    ] 
} 

但所有這些沒有產生我想製作的文件清單。你對這項任務有什麼建議嗎?或者是不可能用couchDB建立這樣的過濾結果? 非常感謝您提前!

回答

6

在一個長的一維列表中,鍵總是從最小到最高排序。 (我試圖在The Parable of CouchDB中直觀地描述這一點,但不知道我是否成功!)

什麼是數組排序從最小到最大的樣子?如果您閱讀視圖中的所有鍵,則左側的值會變化最小;中間值比左側變化更多;而右側的值變化最大。換句話說,數組密鑰告訴CouchDB,「首要任務是按key[0]排序,如果相等,那麼決勝將是key[1];如果那些也相等,那麼下一個決勝者是key[2]等等......」

因此,你可能希望你的按鍵看起來像這樣:

[ "receiver_1", null  , a_date  ], 
[ "receiver_1", "sender_A", some_date ], 
[ "receiver_1", "sender_B", another_date ], 
[ "receiver_2", "sender_A", fourth_date ], 
[ "receiver_3", "sender_C", fifth_date ], 

要找到sender_B爲receiver_1所有消息還公開信息,你需要兩個查詢,一個用於"receiver_1", null配對,而另一個用於"receiver_1", "sender_B"。你想知道任何日期,所以你需要一個範圍與發送者/接收者匹配的行。不幸的是,HTTP POST查詢不支持這一點。

您可以簡單地查詢每個選定的發件人(甚至所有的同時使用線程或異步編程)。接收者和發件人是已知的,並且此示例允許範圍從最小值(null)到最大({}),其中將包含所有日期。

?startkey=["receiver_1",null,null]&endkey=["receiver_1",null,{}] 
?startkey=["receiver_1","sender_B",null]&endkey=["receiver_1","sender_B",{}] 

另一種方法是簡化您的密鑰並刪除日期。

[ "receiver_1", null  ], 
[ "receiver_1", "sender_A"], 
[ "receiver_1", "sender_B"], 
[ "receiver_2", "sender_A"], 
[ "receiver_3", "sender_C"], 
[ "receiver_3", "sender_C"], 
[ "receiver_3", "sender_C"], 
[ "receiver_3", "sender_C"], 
[ "receiver_3", "sender_C"], 

現在您可以再次使用HTTP POST API進行查詢。消息將返回而不是按日期排序。這並不是很糟糕,你可以在客戶端上對它們進行排序(或_list函數)。請記住,即使在我的第一個例子中,日期也沒有完全排序。

+0

感謝您的回覆,我不得不認識到,對於couchDB來說,新手首先應該瞭解的是,沒有任何通配符是@ user787145所說的。我學到的另一件事是,事實上,視圖可以從一個起始索引讀到給定的結束索引,而不會在創建視圖後從列表中過濾掉一些文檔。這導致了觀點本身必須包括過濾特徵的結論。無論如何,似乎你的第三種方法是最適合我的用例。 – sics

5

我想你想要;

emit([doc.author, doc.receiver[idx], doc.date], null); 

可以再用

startkey=["USERID1","USERID2"]&endkey=["USERID1","USERID2",{}] 

此查詢將返回USERID1按照日期順序發送到USERID2所有文件。 {}是一個空對象,並且按照CouchDB歸類規則,將排序比任何數字或字符串更高,因此此處的範圍將保證包含所有可能的日期。

最後,我會注意到CouchDB不支持通配符。

+0

謝謝你的回覆!因爲@JasonSmith的回覆更加詳細,我決定將他的回答標記爲回覆 - 但我也喜歡你的回覆! – sics