2013-05-13 48 views
0

我有一個CouchDB包含一些名爲save_data(我需要的實際數據),rel(作爲相關帳戶 - 帳戶鏈接到該文檔)和created_at(創建日期) 。 當我第一次創建我稱之爲最近項目的視圖時,我認爲該視圖中的項目按照它們的創建順序進行排序,但是我花了很長時間才發現我的錯誤。我想獲得與一個用戶的所有文件(在我的JS相對,save_profile它調用db.view funcion),然後根據created_at排序他們,所以我創建的地圖funcion:Couchdb反轉開始和結束鍵,當降序爲真

function(doc) { 
    if (doc.rel) { 
    var p = doc.save_data || {}; 
    var r = doc.rel || {}; 
    var q = doc.created_at || {}; 
    emit([doc.rel], {save_data: doc.save_data, rel: doc.rel}); 
    } 
}; 

,然後我把它叫做與這些參數:

db.view(design + "/recent-items", { 
    descending : "true", 
    limit : 10, 
    update_seq : true, 
    key : [save_profile], 
    success : function(data) { 
     ...somecode... 
} 
}); 

,然後我發現他們並沒有出現在我想要的順序,而是由他們的ID現在是有意義的排序,但是這不是我所需要的。所以我這樣做:我返工地圖功能,使得它顯示用戶和日期鍵(如字段被排序)

function(doc) { 
    if (doc.rel) { 
    var p = doc.save_data || {}; 
    var r = doc.rel || {}; 
    var q = doc.created_at || {}; 
    emit([doc.rel, doc.created_at], {save_data: doc.save_data, rel: doc.rel}); 
    } 
}; 

,然後我用startkey代替鍵db.view這樣的:

db.view(design + "/recent-items", { 
    descending : "true", 
    limit : 10, 
    update_seq : true, 
    startkey : [save_profile, null], 
    success : function(data) { 
     ...somecode... 
} 
}); 

這樣我就可以獲得所有與save_profile相關的文檔,但也按日期排序。我確實得到了它們,但是我也從其他用戶那裏獲得了它的文檔,所以這個函數是完全不可靠的。我所做的就是實現endkey,像這樣:

db.view(design + "/recent-items", { 
    descending : "true", 
    limit : 10, 
    update_seq : true, 
    startkey : [save_profile, null], 
    endkey : [save_profile, {}], 
    success : function(data) { 
     ...somecode... 
} 
}); 

但是然後我得到空視圖的結果。 日期我用的都是這種格式:

"2013-05-13T11:59:22.281Z" 

和配置文件是這樣的:

{"rand":"0.26928815129213035","nickname":"Nickname","email":"Label for Gravatar","url":"URL","gravatar_url":"http://www.gravatar.com/avatar/35838c85593335493a1fa916863fee0c.jpg?s=40&d=identicon","name":"testacc"} 

我也試過更換[]和{}在開始/ endkeys與「0000-00-00T00 :00:00.000Z「和」9999-99-99T99:99:99.999Z「,但它沒有改變。那麼......任何想法?就我在其他類似問題中看到的,人們只是使用{}作爲結束鍵,並且沒有第二個參數就離開了startkey,但在這裏也不起作用。

編輯:解決! 好的人,不管你信不信,我這樣做了: 我改變了我的地圖功能,以顯示這種方式在和配置文件創建:

function(doc) { 
    if (doc.rel) { 
    var p = doc.save_data || {}; 
    var r = doc.rel || {}; 
    var q = doc.created_at || {}; 
    emit([doc.rel, doc.created_at], {save_data: doc.save_data, rel: doc.rel}); 
    } 
}; 

,看來,如果將下降到真設置開始和結束鍵之前,你必須反向搜索區間,使endkey包含初始值和startkey containst終值,就像這樣:

db.view(design + "/recent-items", { 
    descending : "true", 
    update_seq : "true", 
    startkey : [save_profile.name, save_profile.rand, {}], 
    endkey : [save_profile.name, save_profile.rand, null], 
    inclusive_end : "true", 
    success : function(data) { 
     ...somecode... 
    } 
}); 

這奏效了,它完美的作品(但也有完全沒有的邏輯)。

+0

嗯,這有點不可思議。 – 2013-05-14 14:56:20

回答

0

好的人,不管你信不信,我這樣做了: 我改變了我的地圖功能,顯示在並以這種方式配置文件中創建:

function(doc) { 
    if (doc.rel) { 
    var p = doc.save_data || {}; 
    var r = doc.rel || {}; 
    var q = doc.created_at || {}; 
    emit([doc.rel, doc.created_at], {save_data: doc.save_data, rel: doc.rel}); 
    } 
}; 

,看來,如果你設置下降到真正的設置開始和結束鍵之前,你必須讓endkey包含初始值和startkey containst終值,這樣反向搜索區間:

db.view(design + "/recent-items", { 
    descending : "true", 
    update_seq : "true", 
    startkey : [save_profile.name, save_profile.rand, {}], 
    endkey : [save_profile.name, save_profile.rand, null], 
    inclusive_end : "true", 
    success : function(data) { 
     ...somecode... 
    } 
}); 

這奏效了,它完美的作品(但也有一個完整的abse邏輯)。

0

我認爲startkey [save_profile,null]是什麼讓你煩惱(雖然它通過curl工作)。無論你使用的是什麼庫(db.view是一些javascript lib或ruby CouchRest可能?)可能被重新編碼爲null。你可以通過分解數據包嗅探器(即Wireshark)來驗證這一點,而不是通過分析嗅探器(即Wireshark)來驗證這一點,儘管你會明白一個庫可以滿足所有額外請求的效率。可以使故障排除更加困難。

你用捲曲得到了什麼結果?我嘲笑你的數據庫,這裏就是我得到:我不是使用空

$ curl -X GET 'http://localhost:5984/test2/_design/test_views/_view/view1' 
{"total_rows":4,"offset":0,"rows":[ 
{"id":"test1","key":["account1","2009-05-13T11:59:22.281Z"],"value":{"rel":"account1"}}, 
{"id":"test2","key":["account2","2012-05-13T11:59:22.281Z"],"value":{"rel":"account2"}}, 
{"id":"test3","key":["account3","2011-05-13T11:59:22.281Z"],"value":{"rel":"account3"}}, 
{"id":"test4","key":["account4","2010-05-13T11:59:22.281Z"],"value":{"rel":"account4"}} 
]} 

$ curl -X GET 'http://localhost:5984/test2/_design/test_views/_view/view1?startkey=\["account2"\]&endkey=\["account3",\{\}\]' 
{"total_rows":4,"offset":1,"rows":[ 
{"id":"test2","key":["account2","2012-05-13T11:59:22.281Z"],"value":{"rel":"account2"}}, 
{"id":"test3","key":["account3","2011-05-13T11:59:22.281Z"],"value":{"rel":"account3"}} 
]} 

注意,我只是離開摳出的那個元素。另外注意捲曲(可能你是圖書館),你必須非常小心你在開始/結束鍵中輸入的內容。我必須逃避所有bash的東西,即使單引號也不會逃脫(即[{etc),並且curl將空格轉義爲%20,然後將其用於鍵。一個好的方法是運行couchdb不分叉,或者只是看它的日誌,看看傳入的請求是什麼樣的。一直是我的問題的來源。

您在按鍵中使用通配符,這是一項很酷的功能。您可能已經看過this,我已經重複閱讀了這段代碼,嘗試瞭解它們。

我也在這個類似的問題上打了我的腦袋,直到我真正理解了什麼意見。但你在做什麼應該是可能的。任何更復雜的搜索,我真的會考慮Elasticsearch或類似的東西。河的安裝非常簡單,查詢非常相似。但是,您不必解決視圖和訂單的侷限性。

希望有所幫助。

+0

它確實幫助我,讓我知道思考的方向,但並不直接解決我的問題。非常感謝您的時間,我會嘗試從 – 2013-05-14 10:28:48

+0

的這一點上找到問題。是的,我正在使用CouchRest,它們的代碼可以轉義特殊字符(例如,如您所說的%20)。 – 2013-05-14 10:38:11

+0

我也嘗試過startkey = [個人資料],endkey = [個人資料,{}],我得到了相同的結果 - 空白名單 – 2013-05-14 10:43:10

4

我應該之前就抓到過。所以,當你做到以下幾點,它的作品你喜歡的方式:

db.view('_design/test_views/_view/view1', startkey: ["account2"]) 
=> {"total_rows"db.view('_design/test_views/_view/view1') 
=> {"total_rows"=>4, "offset"=>0, "rows"=>[{"id"=>"test1", "key"=>["account1", "2009-05-13T11:59:22.281Z"], "value"=>{"rel"=>"account1"}}, {"id"=>"test2", "key"=>["account2", "2012-05-13T11:59:22.281Z"], "value"=>{"rel"=>"account2"}}, {"id"=>"test3", "key"=>["account3", "2011-05-13T11:59:22.281Z"], "value"=>{"rel"=>"account3"}}, {"id"=>"test4", "key"=>["account4", "2010-05-13T11:59:22.281Z"], "value"=>{"rel"=>"account4"}}]}` 
db.view('_design/test_views/_view/view1',startkey: ["account2"]) 
=> {"total_rows"=>4, "offset"=>1, "rows"=>[{"id"=>"test2", "key"=>["account2", "2012-05-13T11:59:22.281Z"], "value"=>{"rel"=>"account2"}}, {"id"=>"test3", "key"=>["account3", "2011-05-13T11:59:22.281Z"], "value"=>{"rel"=>"account3"}}, {"id"=>"test4", "key"=>["account4", "2010-05-13T11:59:22.281Z"], "value"=>{"rel"=>"account4"}}]}` 
db.view('_design/test_views/_view/view1', 
    startkey: ["account2"], 
    endkey: ["account3",{}]) 
=> {"total_rows"=>4, "offset"=>1, "rows"=>[{"id"=>"test2", "key"=>["account2", "2012-05-13T11:59:22.281Z"], "value"=>{"rel"=>"account2"}}, {"id"=>"test3", "key"=>["account3", "2011-05-13T11:59:22.281Z"], "value"=>{"rel"=>"account3"}}]}`. 

但是當你設置下降=真,你先顛倒順序。以前,您應按降序=假設置開始和結束鍵的方式,但在更改降序時需要將其撤銷。 CouchDB權威指南非常好,並討論了這些值得閱讀的reversed results

我完全錯過了你設置降序,抱歉的混淆。

+0

沒問題謝謝你的時間。儘管我的代表仍然有點低,但我很樂意投票迴應你的回覆,但我會盡快做到這一點。 – 2013-05-15 10:30:49

+0

沒問題,我不是在尋找布朗尼點。 :) – 2013-05-15 17:03:21