【问题标题】:How to join denormalized data that goes two+ levels deep in Firebase如何加入在 Firebase 中深入两层以上的非规范化数据
【发布时间】:2014-06-01 03:24:40
【问题描述】:

以下是场景:我有一个主题列表,每个主题都包含帖子,每个帖子都被用户列表“点赞”。因此我的数据看起来像这样:

"topics": {
    "topic1": {
        "posts": {
            "post1": true,
            "post2": true
        }
     }
 },
 "posts": {
     "post1": {
         "title": "An awesome post",
         "likes": {
             "user1": true
         }
     },
     "post2": {
         "title": "An even better post",
         "likes": {
             "user1": true,
             "user2": true
         }
     }
 },
 "users": {
     "user1": {
         "name": "Mr. T",
         "email": "t@t.com"
     },
     "user2": {
         "name": "Mr. Hello World",
         "email": "hello@world.com"
     }
 }

我(我想我)知道如何使用 Firebase.util (http://firebase.github.io/firebase-util) 获取该主题的所有帖子:

Firebase.util.intersection(
    fb.child('topics').child('topic1').child('posts'),
    fb.child('posts')
)

但现在我希望每个帖子都包含喜欢该帖子的用户的姓名。如何做到这一点?

可能不会改变任何东西,但这一切都发生在 AngularFire 中。

【问题讨论】:

  • 你没有问你想查询什么。是否所有帖子都被一位用户喜欢?还是所有喜欢某个主题的帖子的用户?
  • 抱歉不清楚。在这种情况下,我想查看所有喜欢帖子的用户的姓名。因此,如果您正在查看帖子/post2,我希望看到“T 先生和 Hello World 先生点赞!”
  • 所以不要在喜欢中使用“true”作为值,你可以使用他的名字
  • 很公平。我认为来自 SQL 背景,我对真正非规范化我的数据犹豫不决(而是遵循这里的建议 firebase.com/blog/2013-04-12-denormalizing-is-normal.html),但也许我应该硬着头皮在任何地方进行非规范化。感谢您查看此内容并分享您的想法。

标签: firebase firebase-realtime-database angularfire nosql


【解决方案1】:

See a working example here

这种非规范化的要点是在您抓取帖子时获取用户。没有什么比听起来更复杂的了。去拿吧。

Firebase 在内部做了大量工作来优化请求并为所有侦听器重复使用相同的套接字连接,因此这是非常高效的 - 几乎不会比正在下载的字节量更多的开销,无论它们是否被拆分进入单独的路径或存储在一起。

HTML:

<h3>Normalizing user profiles into posts</h3>

<ul ng-controller="ctrl">
    <li ng-repeat="post in posts | orderByPriority" ng-init="user = users.$load(post.user)">
        {{user.name}}: {{post.title}}
    </li>
</ul>

JavaScript:

var app = angular.module('app', ['firebase']);
var fb = new Firebase(URL);

app.controller('ctrl', function ($scope, $firebase, userCache) {
    $scope.posts = $firebase(fb.child('posts'));
    $scope.users = userCache(fb.child('users'));
});

app.factory('userCache', function ($firebase) {
    return function (ref) {
        var cachedUsers = {};
        cachedUsers.$load = function (id) {
            if( !cachedUsers.hasOwnProperty(id) ) {
                cachedUsers[id] = $firebase(ref.child(id));
            }
            return cachedUsers[id];
        };
        cachedUsers.$dispose = function () {
            angular.forEach(cachedUsers, function (user) {
                user.$off();
            });
        };
        return cachedUsers;
    }
});

【讨论】:

  • 谢谢加藤。这太棒了。尽管 Firebase 为使事情变得超级高效而做了所有的事情,但如果数据更加完全非规范化(即所有用户信息都被复制)还是性能基本相同,性能仍然会更高吗?
  • 当然更少的请求会更快,至少在最初是这样。但与大多数事情一样,除非存在实际问题,否则不应该进行优化。正如您在小提琴中看到的那样,它太快了,甚至没有注意到它进行了三个往返。在几百条记录中,它可能很明显,但可能仍然相当高效。
猜你喜欢
  • 2015-08-22
  • 1970-01-01
  • 2016-06-20
  • 2021-10-04
相关资源
最近更新 更多