下面我有一个假设的模型,使用node-mongodb-native-drive
A01有一个直系子( A03 )、一个孙子( A04 )和一个曾孙( A05 ):A01 -> A03 -> A04 -> A05
A02有一个直接子级(A06)
如果一个孩子得了分,所有的家长都会得分。例如,如果我给A05评分,那么所有的家长(A01到A04)都会得到一个分数
[{
_id: 'A01',
p_id: '', // parent _id
score: 0,
}, {
_id: 'A02',
p_id: '',
score: 0,
}, {
_id: 'A03',
p_id: 'A01',
score: 0,
}, {
_id: 'A04',
p_id: 'A03',
score: 0,
}, {
_id: 'A05',
p_id: 'A04',
score: 0,
}, {
_id: 'A06',
p_id: '',
score: 0,
},
{
_id: 'A07',
p_id: 'A02',
score: 0,
}, {
_id: 'A08',
p_id: '',
score: 0,
}]
// my naive implementation
function updateScore({ _id, score }) {
return db.collection
.findOneAndUpdate({ _id: }, { $inc: { score } })
.then(function ({ value }) {
if (value && value.p_id) return updateScore({ _id: value.p_id, score }) // recursively update the parent score
return Promise.resolve() // if no parent is found
})
.catch(function (error) {})
}
updateScore({ _id: 'A05', score: 1 })在我的原始函数中,应用程序向mongo服务器发送一个查询(将A05的分数加1)。mongo服务器接收查询并运行它,将一些数据返回给应用程序。应用程序检查是否有父_id,如果有,它会将查询发送到mongo服务器。重复该过程,直到没有父_id为止。
我的想法是,在应用程序和mongo服务器之间来回发送数据不是最好的选择,因为(1)如果mongo服务器是远程托管的,那么延迟;(2)如果数据量很大,则会消耗带宽。
我查看了bulkWrite,但当它不知道p_id时,它无法更新
我查看了running js file in mongo shell和Store a JavaScript Function on the Server,前者表示“连接速度快,延迟低”,但它表示“不要在数据库中存储应用程序逻辑”。并且可能不是那么“快”。
所以问题是:在这种情况下,更新所有家长的分数的“最佳”方法是什么?
发布于 2016-07-11 02:19:35
我会考虑。
使用图形数据库代替上面的更新,它允许这些类型的更新和其他一些字段,如“db.collection.update({"family_id": "123"}, { $inc: { score } }).
在任何情况下,您也可以考虑不更新父母的分数,而是在需要计算分数时对他们的孩子求和。对于某些模式更改,您可以使用聚合管道来完成此操作。如果您经常递增而很少查询,这会更有效率。
https://stackoverflow.com/questions/38288905
复制相似问题