forked from Meteor-Community-Packages/denormalize
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cacheCount.js
55 lines (45 loc) · 1.67 KB
/
cacheCount.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import _ from 'lodash'
import {addMigration} from './migrations.js'
Mongo.Collection.prototype.cacheCount = function(options) {
check(options, {
collection:Mongo.Collection,
cacheField:String,
referenceField:String,
selector:Match.Optional(Object),
bypassSchema:Match.Optional(Boolean)
})
let parentCollection = options.bypassSchema && Package['aldeed:collection2'] ? this._collection : this
let childCollection = options.collection
let selector = options.selector || {}
let cacheField = options.cacheField
let referenceField = options.referenceField
let watchedFields = _.union([referenceField], _.keys(selector))
if(referenceField.split(/[.:]/)[0] == cacheField.split(/[.:]/)[0]){
throw new Error('referenceField and cacheField must not share the same top field')
}
function update(child){
let ref = _.get(child, referenceField)
if(ref){
let select = _.merge(selector, {[referenceField]:ref})
parentCollection.update({_id:ref}, {$set:{[cacheField]:childCollection.find(select).count()}})
}
}
function insert(userId, parent){
let select = _.merge(selector, {[referenceField]:parent._id})
parentCollection.update(parent._id, {$set:{[cacheField]:childCollection.find(select).count()}})
}
addMigration(parentCollection, insert, options)
parentCollection.after.insert(insert)
childCollection.after.insert((userId, child) => {
update(child)
})
childCollection.after.update((userId, child, changedFields) => {
if(_.intersection(changedFields, watchedFields).length){
update(child)
update(this.previous)
}
})
childCollection.after.remove((userId, child) => {
update(child)
})
}