在火力地堡的三方关系,(Three-Way Relationship in Firebase)

2019-10-22 18:03发布

我一直在学习了很多关于过去几个月去归一化数据,但我想知道,如果下面的扁平架构的世界是可能的。 我知道如何处理有关三方关系在火力地堡的双向关系,但什么。 让我解释...

我在我的数据库中,5项servicesprovidersserviceAtProviderreviewsusers 。 我希望能够增加providersservices ,反之亦然。

我也想有是一个特定页面的provider一个内部service ,以及为了有评论链接到提供者在那个特定的服务。 页面的URL可能看起来像这样( site.com/serviceId/providerId )。 该评级是特有的providerId该内部serviceId -你不能评价serviceId S或providerId小号分开。

我不知道如何去建立这样一个复杂的关系。 我怎么会加入serviceIdproviderIdserviceAtProvider项目?

这是我到目前为止有:

 "services": {
   "service1": {
     "name": "Hernia Repair",
     "providers": {
       "provider1": true,
       "provider2": true
     }
   }
 },
 "providers": {
   "provider1": { "name": "The Whittington Hospital" },
   "provider2": { "name": "Homerton Hospital" }
 },
 "serviceAtProvider": {
   "service1AtProvider1": { "rating": 4 },
   "service1AtProvider2": { "rating": 3 }
 },
 "reviews": {
   "service1AtProvider1": {
     "review1": {
       "body": "A review from user 1",
       "user": "user1"
     }
   },
   "service1AtProvider2": {
     "review1": {
       "body": "A review from user 2",
       "user": "user2"
     }
   }
 },
 "users": {
   "user1": { "name": "Ben Thomas" },
   "user2": { "name": "Beatrix Potter" }
 }

我不知道如何创建serviceAtProvider加入,否则我将如何去访问service1.nameprovider1.nameservice1AtProvider1.ratingreviews.service1AtProvider1一个页面上。 谁能解释如何做到这一点?

此外,是否有我应该遵循的最佳做法?

任何帮助表示赞赏。 提前致谢!

UPDATE

{
  "availableServices": {
    "service1": { "name": "Hernia Repair" },
    "service2": { "name": "Chemotherapy" }
  },

  "services": {
    "provider": {
      "name": "The Whittington Hospital",
      "service": {
        "service1": {
          "rating": 4,
          "reviewId1": true
        },
        "service2": {
          "rating": 3,
          "reviewId2": true
        },
      }
    }
  },

  "reviews": {
    "reviewId1": {
      "review1": {
        "rating": 4,
        "body": "A review from user 1",
        "user": "user1"
      }
    }
  },

  "users": {
    "user1": { "name": "Raphael Essoo-Snowdon" },
    "user2": { "name": "Sharlyne Slassi" }
  }
}

Answer 1:

我会通过使数据结构简单一点,更直接的开始。 很难确定您需要的正确的数据结构没有详细使用情况。 我会尽我所能在这里提出一些通用的假设。 你必须根据需要适应。

{
  "service": {
    "service1": { "name": "Foo Service" }, 
    ...
  },

  "provider": {
     "provider1": { name: "Foo Place" }, 
     ...
  },

  "ratings": {
    "service1": { // service id
      "provider1": {  // provider id
        "average_rating": 4
      },
      ...
    },
    ...
  },

  "reviews": {
    "service1": { // service id
      "provider1": {  // provider id
        "user": "user1",
        "rating": 4
      },
      ...
    },
    ...
  },

  "user": {
    "user1": { "name": "Foo Bar" },
    ...
  }
}

现在,查找谁提供给定的服务提供者,并抓住他们的评论,我会做到以下几点:

var ref = new Firebase(...);
ref.child('ratings/service1').on('child_added', function(reviewSnap) {
   console.log(
      'Provider ' + reviewSnap.key(),
      'Average rating ' + reviewSnap.val().average_rating
   );
});

在服务和供应商的名称加入能以几种方式来完成。 这里有一个手工技艺:

var ref = new Firebase(...);
ref.child('ratings/service1').on('child_added', accumulateReview);

function accumulateReview(reviewSnap) {
  var reviewData = reviewSnap.val();
  var reviewid = reviewSnap.key();
  fetchService(reviewSnap.parent().key(), function(serviceSnap) {
    loadRec('provider', reviewSnap.key(), function(providerSnap) {
        console.log('Provider: ', providerSnap.key(), providerSnap.val().name);
        console.log('Service: ', serviceSnap.key(), serviceSnap.val().name);
        console.log('Average rating: ', reviewData.average_rating);
    });
  });
}

var serviceCache = {};
function fetchService(serviceid, done) {
  // demonstrates creating a local cache for things that will be
  // looked up frequently 
  if( !serviceCache.hasOwnProperty(serviceid) ) {
    cacheService(serviceid, done);
  }
  else {
    done(serviceCache[serviceid]);
  }
}

function cacheService(serviceid, done) {
  loadRec('service', function(ss) {
    serviceCache[serviceid] = ss;
    fetchService(serviceid, done);
  });
}

function loadRec(type, key, done) {
  ref.child(type).child(key).once('value', done);
}

我还可以自动完成一些与Firebase.util的这个过程NormalizedCollection :

var ref = new Firebase(...);
var nc = Firebase.util.NormalizedCollection(
   [ref.child('reviews/service1'), 'review'],
   ref.child('provider'),
   ref.child('user')
)
.select('review.rating', {key: 'provider.name', alias: 'providerName'}, {key: 'user.name', alias: 'userName'})
.ref();

nc.on('child_added', function(snap) {
  var data = snap.val();
  console.log('Provider', data.providerName);
  console.log('User', data.userName);
  console.log('Rating', data.rating);
});

请注意,这里没有什么是一成不变的。 这是我会怎么处理它。 大概有几十结构至少一样好或更好的。



文章来源: Three-Way Relationship in Firebase