2017-02-22 81 views
2

有一個帳戶文檔。這個文件有1k個席位。對於每個席位,我們發出一個文檔。自然,你會期望這會很慢。地圖功能像這樣運行:Couchdb超慢視圖,100%cpu使用率

function(doc) { 
    if (doc.type == 'account') { 
     doc.seats.map(function(seat) { 
      emit(seat.userID, doc)) 
     } 
    } 
} 

但是,刪除doc.seats,然後發佈更小的文檔似乎沒有幫助。

function(doc) { 
    if (doc.type == 'account') { 
     doc.seats.map(function(seat) { 
      delete doc.seats 
      emit(seat.userID, doc)) 
     } 
    } 
} 

有沒有人明白爲什麼刪除座位不加快速度?我們唯一可以加速的方式是不發佈doc對象,只是發佈一個id。

function(doc) { 
    if (doc.type == 'account') { 
     doc.seats.map(function(seat) { 
      emit(seat.userID, doc.id)) 
     } 
    } 
} 

這是一個循環在沙發視圖地圖上的文檔的數組問題?

回答

5

tldr;

  1. ,如果你關心性能
  2. 文檔是從視圖一成不變使用永久視圖。你甚至不能在沒有複製的情況下添加它。
  3. 發出_id並使用include_docs幾乎總是比發送整個doc作爲值更好。

解釋

這裏有幾點你的問題,使用含有所謂的座椅,1K條目的數組的示例文檔。

在這裏發射整個文檔是一個壞主意。如果這是一個永久性視圖(如果性能完全成問題,您應該始終使用該視圖),則您已獲取一份doc副本,然後製作1000個副本並通過seat.userID對其進行索引。這不是有效的。它作爲一個臨時視圖更糟糕,因爲它隨即在內存中每次調用視圖時生成。

AFAIK該文檔是完全不可變的,因爲通過視圖訪問,所以您試圖刪除座位字段的方式不起作用。因此,刪除doc.seats不應該提供任何性能增益,因爲您仍然要完成循環並創建1000個原始文檔副本。但是,您可以製作一份沒有席位的文檔的深層副本,並將其通過發佈。

例如:

function(doc) { 
    var doc_without_seats = JSON.parse(JSON.stringify(doc)) 
    doc_without_seats['seats'] = null; 
    doc.seats.map(function (seat){ 
    emit(seat.userID, doc_without_seats); 
    }); 
} 

你肯定是在正確的軌道上發射doc._id代替DOC的。你在這種情況下建立的索引是最大的,是1/1000的大小。如果仍然需要訪問整個文檔,則可以在查詢時將選項include_docs = true傳遞給視圖。這可以防止整個文檔被複制到索引中。

另一個潛在的優化可能是在seat.userID查找某些東西時發佈您想要參考的內容。如果這仍然很大並且很笨重,請使用include_docs方法。

+0

就數據而言,原始文檔是99%的座位數組。所以如果我發出減去該數組的文檔,是不是應該給予提振? - 其實,回頭看我的代碼,刪除可能不會像我期望的那樣工作,因爲我正在運行它。map()方法 – Elliot

+0

啊,我相信doc是不可變的。查看我的更新。 – sarwar