Noo*_*ter 6 javascript mongoose mongodb node.js
我通过无限卷轴一次装入12个大块的产品.
有时,我可能想根据他们有多少粉丝对这些进行排序.
以下是我如何跟踪每个产品有多少粉丝.
由于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
}
});
Run Code Online (Sandbox Code Playgroud)
遵循架构的产品:
var ProductSchema = new mongoose.Schema({
name: {
type: String,
unique: true,
required: true
},
followers: {
type: Number,
default: 0
}
});
Run Code Online (Sandbox Code Playgroud)
每当用户关注/取消关注产品时,我都会运行此功能:
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);
})
};
Run Code Online (Sandbox Code Playgroud)
我对此有疑问:
1:产品中增加的"跟随者"值是否有可能遇到某种错误,导致数据不匹配/不一致?
2:为每个产品编写一个聚合来计算关注者会更好吗,还是会太昂贵/慢?
最终,我可能会在graphDB中重写它,因为它似乎更适合,但是现在 - 这是掌握MongoDB的练习.
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)
Run Code Online (Sandbox Code Playgroud)
输出:
time: 1.230138
time: 3.620147
Run Code Online (Sandbox Code Playgroud)
创建索引可以加快查找查询速度。
db.products.createIndex({followers: 1})
time: 0.174761
time: 3.604628
Run Code Online (Sandbox Code Playgroud)
如果您需要产品的属性(例如名称),则需要另一个 O(n) 查询。
我猜当数据规模扩大时,聚合会慢得多。如果需要,我可以对大规模数据进行基准测试。
| 归档时间: |
|
| 查看次数: |
260 次 |
| 最近记录: |