Léo
Léo

Reputation: 53

How to count documents by specific criteria in firebase nodejs?

I want to implement a cloud function with firebase nodejs in javascript to count the number of documents that have a specific value for one of their propertie. I am looking for something like this :

exports.countDocumentsWithSpecificProp= functions.https.onCall((data, context)=>{
    var num = admin.firestore().collection('users').where("propToCheck", "==", data["propToCheck"]).length;
    return num;
});

where 'propToCheck' is a user propertie and data the argument I give from my app.

Upvotes: 0

Views: 419

Answers (1)

Michael Bleigh
Michael Bleigh

Reputation: 26313

The code you have is close to something that would work. This will do what you ask:

exports.countDocumentsWithSpecificProp= functions.https.onCall(async (data, context)=>{
    const snap = await admin.firestore().collection('users').where("propToCheck", "==", data["propToCheck"]).get();
    return {count: snap.docs.length};
});

However, this incurs full document reads for every document matching the query and you will be charged accordingly. It is likely to be inefficient and, if you're talking about tens of thousands or more of documents, expensive and too slow to be a reasonable solution.

Generally with Firestore you'll want to dynamically increment counters as documents are written. For instance, you could store a count in a separate collection by incrementing when documents are created. In a simplified example:

exports.countPropToCheck = functions.firestore.document('users/{userId}').onCreate(async (snap, context) => {
  const valueToCount = snap.get('propToCheck');
  await admin.firestore().collection('propToCheckCounts')
    .doc(valueToCount).update({count: admin.firestore.FieldValue.increment(1)});
});

exports.countDocumentsWithSpecificProp = functions.https.onCall(async (data, context)=>{
    const snap = await admin.firestore().collection('propToCheckCounts').doc(data["propToCheck"]).get();
    return snap.data();
});

The caveat here is that obviously you have to know ahead of time that you're going to count things on that field. The other caveat is that functions are not guaranteed to execute only once, so if you need a very very exact count you'll need to periodically manually recount.

See these docs on distributed counters for further information about counting in Firestore.

Upvotes: 2

Related Questions