【问题标题】:Firebase functions, counting elements for big dataFirebase 函数,计算大数据的元素
【发布时间】:2017-08-01 08:35:55
【问题描述】:

最近 Firebase 引入了Cloud Functions

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

Firebase 发布了 sample code to count elements,但我问自己一些关于大数据的问题。

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

在示例代码中,每个新的like,函数count all likes for the current post并更新计数。

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

提前谢谢你!

【问题讨论】:

  • 可能不会。为了进行计数,所有数据都必须加载到内存中。最好使用事务来为每个人增加一个数字计数器,并以这种方式对您的数据进行非规范化。
  • 似乎函数只要在单个添加上运行就可以了吗?这应该比将所有数据加载到内存中更好。看起来我们有一个example of this
  • 我将 firebase 与其他更适合这些类型查询的数据库结合使用。您可以使用函数将 Firebase 数据流式传输到 Big Query、Algolia、Graph 数据库或 SQL 数据库,如果您的目标是大数据查询,则可以完成更多工作。

标签: javascript firebase firebase-realtime-database google-cloud-functions


【解决方案1】:

同意函数示例中的代码不适用于大量数据。

长期以来,我在计数器中使用了两步法:

  1. 添加/删除子项时,增加/减少计数器
  2. 当计数器被删除时,重新计算所有子项(就像现在一样)

所以案例 #2 与当前代码一样是内存绑定的。但是第 1 种情况会在子写入时触发,因此占用的内存要少得多。

代码:

// 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 中提交了这个。

【讨论】:

    【解决方案2】:

    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了解更多详情。

    【讨论】:

    • 这个示例代码链接在我的问题中......我的问题是“你认为它是大数据的好解决方案吗?”
    • 啊,对不起。我以为我们在这里讨论的是技术问题而不是意见。 “要求我们推荐或查找书籍、工具、软件库、教程或其他非现场资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,请描述问题和已完成的工作到目前为止解决它。”
    • 我认为它的技术性很强。如果我没有给出足够的精确度,我很抱歉。我知道这个解决方案效果很好,但如果我有很多数据,也许我应该使用其他解决方案。 “event.data.numChildren()”可能非常高。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多