2013-05-01 62 views
4

我一直在試圖找到這個需求的解決方案,但我已經擊中了很多死衚衕。基於對象屬性值在Cloudant(CouchDB)中創建視圖

我正在使用Cloudant作爲我的用戶文檔的數據存儲。每個用戶文檔都有一個名爲'items'的字段(屬性),它是一個對象數組。

所以用戶文件看起來是這樣的:

{ 
    "_id":"userid1", 
    "_rev":"XX", 
    "username": "foobaruser" 
    "items": 
    [ 
     { 
      "date":1357879144069, 
      "text":"don't cry because it's over, smile because it happened.", 
      "cat":"determination" 
     }, 
     { 
      "date":1357879179209, 
      "text":"those who mind don't matter, and those who matter don't mind.", 
      "cat":"fitness" 
     }, 
     { 
      "date":1357883809736, 
      "text":"be the change that you wish to see in the world.", 
      "cat":"determination" 
     }, 
     { 
      "date":1357879179209, 
      "text":"those who mind don't matter, and those who matter don't mind.", 
      "cat":"hardwork" 
     }, 
     { 
      "date":1357879179209, 
      "text":"those who mind don't matter, and those who matter don't mind.", 
      "cat":"determination" 
     } 
    ] 
} 
  • 有在數據存儲這樣的多個用戶的文件和每個文件都有屬性「項」

要求:

  1. 理想情況下,我想在視圖上使用搜索功能併爲「貓」傳遞一個值,然後返回與「貓」值相匹配的所有文檔中的所有「項目」。

    例如 https:// [username] .cloudant.com/dbname/_design/views/_search/doc?q =確定

  2. 上述搜索將返回所有用戶文檔中「items」貓=決心」的格式與此類似:

    { 
        "total_rows": 2, 
        "rows": 
        [{ 
         "id": "userid1", 
         "items": 
         [ 
          { 
           "date":1357879144069, 
           "text":"don't cry because it's over, smile because it happened.", 
           "cat":"determination" 
          }, 
          { 
           "date":1357883809736, 
           "text":"be the change that you wish to see in the world.", 
           "cat":"determination" 
          }, 
          { 
           "date":1357879179209, 
           "text":"those who mind don't matter, and those who matter don't mind.", 
           "cat":"determination" 
          } 
         ] 
        }, 
        { 
         "id": "userid2", 
         "items": 
         [ 
          { 
           "date":135787966655, 
           "text":"Some text", 
           "cat":"determination" 
          } 
         ] 
        }] 
    } 
    
  3. 如果使用是不可能的‘搜索’,則是有可能使用次級索引來實現這一目標?

+0

你試試吧:

function(doc){ if (doc.items) { for (var n in doc.items) { if (doc.items[n].cat) { index("cat", doc.items[n].cat, { store : true }); } } } } 

您可以在搜索作爲查詢呢?如果它沒有做你想做的事,你需要創建一個視圖。 – WiredPrairie 2013-05-01 11:17:23

+0

對不起,不知道你的意思。我嘗試了什麼? – newbreedofgeek 2013-05-01 23:36:56

+0

您是否嘗試過搜索?它可能適合您的需求(並且您處於最佳位置嘗試它並查看它是否有效)。 – WiredPrairie 2013-05-02 01:14:28

回答

5

在CouchDB中,您無法將查詢參數的動態值傳遞給視圖(您的情況爲cat =確定)。 CouchDB中的方法是創建一個更一般的視圖,然後在調用視圖來調整您需要的數據時調整結果的排序方式。

你需要你的數據庫的設計文檔來實現這一來創建自定義視圖:

byUserItemCat: { 
    map: function (doc) { 
     if (!doc.items || doc.items.length === 0) return; 
     for (var i=0; i<doc.items.length; i++) { 
      emit(doc.items[i].cat,{doc._id,doc.items[i].date,doc.items[i].text}); 
     } 
    } 
} 

所以上述觀點會爲每個文檔的數據庫,檢查它有一個項目數組內容,然後循環所有文檔的項目。對於每個項目元素,它會發現它將cat作爲索引發布到結果集中,這很重要,因爲我們可以對此索引進行排序。我們可以自由地構建結果對象,我們喜歡(第二個參數爲emit),在上面的例子中,我使用用戶ID和項目的日期和文本構建一個對象。

你會打電話來的觀點是這樣的,讓所有的結果:

curl -X GET http://127.0.0.1:5984/<db-name>/_design/<design-doc-name>/_view/byUserItemCat 

如果你只是感興趣的結果,其中索引鍵(即cat)是「決心」你」 d do:

curl -X GET http://127.0.0.1:5984/<db-name>/_design/<design-doc-name>/_view/byUserItemCat?key="determination" 
+0

這正是我一直在尋找的感謝!我還改善了數據模型,因爲如果數組增長的話,我給出的嵌套模型會有問題。 – newbreedofgeek 2014-10-29 01:54:34

1

Cloudant的搜索以返回文檔的粒度工作。您的索引功能可以索引文檔中item s中正在使用的類別,然後您的搜索將返回包含item s的文檔與您提及的類別。然後,您的應用程序代碼將需要過濾到item以返回到客戶端。

您的索引功能會是這樣的(無恥地從Wintamute惡癖):

if (!doc.items || doc.items.length === 0) return; 
var item; 
for (var i=0; i<doc.items.length; i++) { 
    index("cat", doc.items[i].cat, {"index": "not_analyzed"}); 
} 

另一種方法是將項目分解到各自的文件,如果你真的希望能夠得到公正的項目。然而,我想第二次(並且已經投票贊成)Wintamute的回答,因爲我同意在這個特定情況下建議的視圖是最好的解決方案(通過cat查找和顯示項目)。

1

這實際上可以通過Cloudant搜索完成。我有一個類似的問題,我需要解決。特別感謝Cloudant的Mike Bresslin的幫助。

?q=cat:hardwork OR cat:determination