Firebase 函数,计算大数据的元素

Firebase functions, counting elements for big data

最近 Firebase 推出 Cloud Functions

在我的例子中,此功能对于计算数据库中的元素非常有用。

Firebase post编辑了 sample code to count elements 但我问了自己一些关于大数据的问题。

在我们的示例中,我们认为我们需要计算 post 的点赞次数。

在示例代码中,在每个新的点赞中,函数计算当前 post 的所有点赞并更新计数。

您认为这是一个很好的大数据解决方案吗? (例如,如果我们有 100 万个赞)

提前致谢!

请参阅 functions-samples 中的示例。

给定一个类似这样的数据结构:

/functions-project-12345
    /posts
        /key-123456
            likes_count: 32
            /likes 
                user123456: true
                user456789: true
                user786245: true
                ...

这个函数可以解决问题:

'use strict';

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

// Keeps track of the length of the 'likes' child list in a separate attribute.
exports.countlikes = functions.database.ref('/posts/{postid}/likes').onWrite(event => {
  return event.data.ref.parent.child('likes_count').set(event.data.numChildren());
});

请注意,此代码拥有版权 Google 并已获得 apache 许可。 See the code了解更多详情。

同意函数示例中的代码不适合大型数据集。

很长一段时间以来,我在我的计数器中使用了 two-stepped 方法:

  1. 当 child 是 added/removed 时,increase/decrease 计数器
  2. 当计数器被删除时,重新计算所有 children(就像现在一样)

所以案例 #2 memory-bound 与当前代码相同。但是案例 #1 在 child 写入时触发,因此内存消耗少了很多。

代码:

// Keeps track of the length of the 'likes' child list in a separate property.
exports.countlikechange = functions.database.ref("/posts/{postid}/likes/{likeid}").onWrite((event) => {
  var collectionRef = event.data.ref.parent;
  var countRef = collectionRef.parent.child('likes_count');

  return countRef.transaction(function(current) {
    if (event.data.exists() && !event.data.previous.exists()) {
      return (current || 0) + 1;
    }
    else if (!event.data.exists() && event.data.previous.exists()) {
      return (current || 0) - 1;
    }
  });
});

// If the number of likes gets deleted, recount the number of likes
exports.recountlikes = functions.database.ref("/posts/{postid}/likes_count").onWrite((event) => {
  if (!event.data.exists()) {
    var counterRef = event.data.ref;
    var collectionRef = counterRef.parent.child('likes');
    return collectionRef.once('value', function(messagesData) {
      return counterRef.set(messagesData.numChildren());
    });
  }
});

我还在回购的 PR 中提交了这个。