2017-04-04 47 views
0

在我的數據庫中,我有這樣的圖片:如何找到未被引用文檔Cloudant

{ 
    "id": "image-1", 
    "type": "image", 
    "href": "..." 
} 

和書籍,其中包括圖片:

{ 
    "id": "book-1", 
    "type": "book", 
    "images": [ 
    "image-1", 
    "image-33" 
    ] 
} 

這是因爲,一個多一對多的關係相同的圖像可以出現在多本書中,使用鍵列表模式進行建模。我可以使用視圖來遍歷另一個方向上的關係,並查找出現給定圖像的書籍。

我的問題是:如何找到沒有出現在任何書中的圖像?

圖像佔用空間,並可能有其他相關費用,因此這些將是很好的候選人刪除。

我首先想到的是使用計數每個圖像的引用數的觀點:

"map": function (doc) { 
    if (doc.type == "book") { 
    for (i = 0; i < doc.images.length; i++) { 
     emit(doc.images[i], null); 
    } 
    } 
    else if (doc.type == "image") { 
    emit(doc._id, null); 
    } 
}, 
"reduce": _count 

如果我說一個圖像引用本身那麼我可以肯定的是,在視圖中存在的所有圖像和我只需要選擇那些只能被自己引用的地方,也就是count爲1的地方。但這就是我被卡住的原因,因爲視圖機制似乎只能讓我過濾掉密鑰而不是數值(count)。

我還考慮創建一個針對book.images成員的索引,然後搜索沒有出現在該索引中的圖像,但我無法找到這些行中的任何示例。

我知道我的潛在解決方案都需要在所有圖像上進行線性搜索,但我確定這是因爲這是一種偶爾運行並且不是時間關鍵的內務操作。在那個程度上,我的第一個選項工作得很好,這只是意味着我必須將整個視圖返回到客戶端,並在那裏搜索時,我更願意在服務器中應用過濾器。

我也知道,如果我改變模型和反向的關係,這樣的圖像包含的書籍列表:

{ 
    "id": "image-1", 
    "type": "image", 
    "href": "...", 
    "books": [ 
    "book-1", 
    "book-12" 
    ] 
} 

然後,我仍然可以使用視圖找到一本書的圖片,但我也可以索引image.books成員並快速找到長度爲0的那些成員。但是,這會給應用程序帶來負擔,因爲應用程序編輯書籍,這意味着只要用戶修改書中的圖像,應用程序就必須也修改圖像,並引入一致性問題,因爲使用不同書籍的兩個用戶最終可能會修改相同的圖像。

+0

那麼隨着你的第一想法,然後用「?group = true」查詢視圖?這將返回每個圖像和數量。你會迭代所有的結果,找到任何1的計數,並刪除這些圖像... – markwatsonatx

+0

@markwatsonatx是的,謝謝,這就是我正在做的 - 對不起,如果我沒有說清楚。它的工作原理,所以我的問題是:我必須把整個(分組)視圖下拉到客戶端並在那裏過濾嗎?或者有沒有辦法在查詢中包含過濾器來減少我的應用程序的負載?或者完全使用其他方法。 –

+0

我想不出在應用程序中增加更多負擔的好方法。我在下面提出了一種替代方法,但我知道這並不能真正解決您的問題。 – markwatsonatx

回答

0

另一種方法是使用分面搜索並僅返回計數。它仍然會返回每個圖像。有效載荷是這樣的:

{ 
    "total_rows": 4, 
    "bookmark": "g2o", 
    "rows": [ ], 
    "counts": { 
    "image": { 
     "image-1": 3.0, 
     "image-2": 1.0, 
     "image-33": 1.0 
    } 
    }  
} 

設計文檔應該是這樣的:

{ 
    "_id": "_design/bookSearch", 
    "_rev": "xxx", 
    "views": {}, 
    "language": "javascript", 
    "indexes": { 
    "search": { 
     "index": "function (doc) {\n if (doc.type == \"image\") {\n index(\"image\", doc.id, {\"facet\": true});\n }\n else if (doc.type == \"book\") {\n for (var i=0; i<doc.images.length; i++) {\n  index(\"image\", doc.images[i], {\"facet\": true});\n }\n }\n}\n", 
     "analyzer": "standard" 
    } 
    } 
} 

功能如下:

function (doc) { 
    if (doc.type == "image") { 
    index("image", doc.id, {"facet": true}); 
    } 
    else if (doc.type == "book") { 
    for (var i=0; i<doc.images.length; i++) { 
     index("image", doc.images[i], {"facet": true}); 
    } 
    } 
} 

查詢應該是這樣的:

https://xxx.cloudant.com/db/_design/bookSearch/_search/search 
?q=*:*&limit=0&counts=["image"] 

不確定是否有嗯真正的優勢,這樣做雖然...

相關問題