2016-12-04 12 views
6

我「通過在同一時間在12塊的無限滾動M狀加載產品。

有時,我會想他們有多少追隨者整理這些。

下面的是我如何跟蹤。有多少追隨者每個產品都有


接踵而來的是在一個單獨的集合,因爲16MB數據帽和量如下應該是無限

如下模式:

var FollowSchema = new mongoose.Schema({ 
    user: { 
     type: mongoose.Schema.ObjectId, 
     ref: 'User' 
    }, 
    product: { 
     type: mongoose.Schema.ObjectId, 
     ref: 'Product' 
    }, 
    timestamp: { 
     type: Date, 
     default: Date.now 
    } 
}); 

產品所遵循的模式:

var ProductSchema = new mongoose.Schema({ 
    name: { 
     type: String, 
     unique: true, 
     required: true 
    }, 
    followers: { 
     type: Number, 
     default: 0 
    } 
}); 

只要用戶遵循/ unfollows一個產品,我運行這個功能:

ProductSchema.statics.updateFollowers = function (productId, val) { 
    return Product 
     .findOneAndUpdateAsync({ 
      _id: productId 
     }, { 
      $inc: { 
       'followers': val 
      } 
     }, { 
      upsert: true, 
      'new': true 
     }) 
     .then(function (updatedProduct) { 
      return updatedProduct; 
     }) 
     .catch(function (err) { 
      console.log('Product follower update err : ', err); 
     }) 
}; 

我對這個問題:

1 :產品中遞增的「跟隨者」值是否有可能遇到某種錯誤,導致不匹配/不匹配持續的數據?

2:倒不如寫一個彙總數對每個產品的追隨者,還是那樣過於昂貴/慢?

最終,我可能會在graphDB改寫這個,因爲它似乎更適合,但現在 - 這是在掌握MongoDB的練習。

+0

關於#1:單個文檔更新是原子性的,但是您要更新2個集合中的2個文檔,這不是全部原子集合。這可能是任何一個步驟都失敗了。例如,跟隨是成功的,但增量失敗。閱讀:[兩階段提交。](https://docs.mongodb.com/v3.2/tutorial/perform-two-phase-commits) –

回答

0

1如果在刪除後插入或減少後增加,這些可能會導致數據不一致。例如,插入成功但遞增失敗。

2直觀地說,聚合比在這種情況下找到的要昂貴得多。我做了一個基準來證明它。

首先隨機生成1000個用戶,1000個產品和10000個關注者。然後,使用此代碼進行基準測試。

import timeit 

from pymongo import MongoClient 
db = MongoClient('mongodb://127.0.0.1/test', tz_aware=True).get_default_database() 

def foo(): 
    result = list(db.products.find().sort('followers', -1).limit(12).skip(12)) 

def bar(): 
    result = list(db.follows.aggregate([ 
     {'$group': {'_id': '$product', 'followers': {'$sum': 1}}}, 
     {'$sort': {'followers': -1}}, 
     {'$skip': 12}, 
     {'$limit': 12} 
    ])) 

if __name__ == '__main__': 
    t = timeit.timeit('foo()', 'from __main__ import foo', number=100) 
    print('time: %f' % t) 

    t = timeit.timeit('bar()', 'from __main__ import bar', number=100) 
    print('time: %f' % t) 

輸出:

time: 1.230138 
time: 3.620147 

創建索引可以加快查找查詢。

db.products.createIndex({followers: 1}) 

time: 0.174761 
time: 3.604628 

,如果你需要從產品的屬性,如名稱,則需要另一種爲O(n)查詢。

我想,當數據放大時,聚合會慢得多。如果需要,我可以在大規模數據上進行基準測試。

0

對於數字1,如果在該領域唯一的操作遞增和遞減,我想你會好起來的。如果您開始複製該數據或因某種原因在連接中使用該數據,則可能會遇到數據不一致的風險。

對於2號,我建議你運行在蒙戈外殼這兩種情況下,測試出來。您也可以review the individual explain plans爲這兩個查詢來了解哪一個會更好地執行。我只是猜測,但似乎更新路線會表現良好。

此外,預期的數據量有差別。它可能在某種程度上表現得很好,但是在一百萬條記錄之後,其他路線可能就是要走的路。如果你有一個測試環境,這是一件好事情來檢查。

0

1)這依賴應用層上執行的一致性,並因此存在將是您結束了不一致的機會。我會問的問題是:在這種情況下一致性有多重要,以及有多大可能存在很大的不一致性?我的想法是,一個追隨者的離開並不像儘可能快地使無限滾動負載來提高用戶的體驗一樣重要。 2)可能值得看的表現,但如果我不得不猜測,我會說這種方法將會放緩。

相關問題