设计集合,如何规范化

时间:2015-02-18 10:17:07

标签: javascript mongodb denormalization

我有许多地方以不同价格提供的服务。在过渡SQL中,我想让price_location表包含service_id,并且location_id在我希望在显示最高价和最低价的某些区域(区域将选择多个位置)中找到服务时进行加入和分组。

由于服务和位置非常多,我想到以下几点:

service_location_price = [
  {
    serviceName:'s1';
    ,price:10
    ,location:'location1'
  },{//to keep it simple only serviceName is here but
     // there will be multiple providers for the same
     // serviceName at same location but different price
    serviceName:'s1';
    ,price:12
    ,location:'location1'
  },{
    serviceName:'s1';
    ,price:15
    ,location:'location2'
  }
];

基本平坦的文件数据打破第二范式(具有重复行)。

现在聚合和/或地图缩减应该可以很好地使某个地区的服务显示最低和最高价格。或显示某些服务的可用位置。

服务和位置都有自己的集合,service_location_price集合会复制此查询的服务和位置值。

有些人担心重复数据,并希望以不同方式实现(mongoose填充匹配??)。

不确定我的选项是什么,所以会感谢来自可能有更多经验的人的一些意见。是否有更好的方法来搜索

服务和位置不会更新太多,但之间的关系可能会更改,添加或删除。但是,地区对服务的搜索将经常执行。

1 个答案:

答案 0 :(得分:1)

填充是一个用于解析引用的大$in查询,然后它会将数组中的引用换成相应的文档。如果参考字段被编入索引并不是那么糟糕,但它是一个额外的查询,它是一个糟糕的模式设计的拐点,因为它可以让你更容易模拟关系数据库;使用关系数据库,应该以不同的方式处理问题。我认为它应该从Mongoose中删除,但遗憾的是有点晚了:(

我不确定你是如何建模区域的 - 你说区域可以是多个位置,所以我会将一个区域建模为location值的数组。

特定地区的服务总数:

db.service_location_price.distinct("serviceName", { "location" : { "$in" : region_array } })

这将为您提供一系列服务名称,因此.length将提供服务数量。

区域内服务的最低/最高价格:

db.service_location_price.find({ "location" : { "$in" : region_array }, "serviceName" : "service1" }).sort({ "price" : 1 }).limit(1)
db.service_location_price.find({ "location" : { "$in" : region_array }, "serviceName" : "service1" }).sort({ "price" : -1 }).limit(1)

示例文档中没有关于服务供应商的信息,因此我不知道如何查找某个地区的服务供应商数量。也许您想在文档中包含supplier字段?