Skip to content

Suggestion: fetch only required fields from db when not in cache #7

@wildhart

Description

@wildhart

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:

  1. Server calls could be more db efficient.
  2. 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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions