-
Notifications
You must be signed in to change notification settings - Fork 7
Description
When the required fields are not available in the cache, userCache simply calls _original() which causes the entire user object to be fetched from the db, even though userCache knows which fields are required.
If instead userCache were to only fetch the requested fields then less data may need to be fetched. If the developer stores lots of custom data on in the users db then this could be a significant saving.
I suggest an improvement similar to the following:
if (typeof input === "object") {
var cache = _getCache()
var innocent = true;
var fields = {};
input.forEach(function (item) {
fields[item] = 1;
if (typeof _getField(cache, item) === "undefined") {
innocent = false;
}
})
if (innocent) {
return cache;
} else {
const userId = Meteor.userId();
return userId ? Meteor.users.findOne(userId, {fields}) : null;
}
}or just;
} else {
const userId = Meteor.userId();
if (!userId) return null;
const fields = {};
input.forEach(item => fields[item] = 1);
return Meteor.users.findOne(userId, {fields});
}whichever you think will be most efficient.
I suggest this because before trying userCache I had hacked Meteor.user() to do precisely this, so that:
- Server calls could be more db efficient.
- Client calls within a reactive computation would recompute only when the required fields are changed.
However, I cannot use my own hack alongside userCache, so I've had to hack userCache to incorporate my own hack.
To provide benefit (2) you might also provide a similar client-side API with this:
Meteor.user = function(fields) {
const userId = Meteor.userId();
if (!userId) return null;
if (typeof fields=='undefined' || fields===true) fields = {};
else if (typeof fields=='string') fields = {[fields]: 1};
else {
const obj = {};
fields.forEach(f => obj[f]=1);
fields = obj;
}
return Meteor.users.findOne(userId, {fields});
}However, although useful, that's a bit beyond the scope of userCache.
What do you think?