Bookshelf.js松散相关数据的关系

时间:2014-03-24 20:32:53

标签: bookshelf.js knex.js

我有一张酒店餐桌和一张舒适餐桌。它们“相关”的唯一方式是通过位置,使用PostGIS for PostgreSQL。在SQL中,我使用这样的查询来查找距离酒店最近的5个设施:

SELECT amenity.name, amenity.brand, ST_Distance_Sphere(hotel.geom, amenity.geom) FROM amenity, hotel WHERE slug='city-plaza' ORDER BY ST_Distance(hotel.geom, amenity.geom) LIMIT 5;

有没有办法可以使用Bookshelf为酒店模型添加“nearestAmenities”字段,这将是Amenity的集合?

2 个答案:

答案 0 :(得分:1)

您是否尝试过使用knex.raw功能?

knex.raw('SELECT amenity.name, amenity.brand, ... LIMIT 5').then(function(resp) {
  ...
});

答案 1 :(得分:1)

我发现的解决方案是除了Bookshelf的belongsToMany功能之外还使用SQL视图。以下是使用上述表名的步骤,以防其他人偶然发现此问题:

1)添加视图'hotel_amenity':

CREATE OR REPLACE VIEW hotel_amenity AS
SELECT h.id         hotel_id,
       a.id         amenity_id,
       ceil(ST_Distance(ST_Transform(h.geom, 3414), ST_Transform(a.geom, 3414))/100)/10 distance_km
  FROM amenity a
  CROSS JOIN hotel h;

2)使用Bookshelf添加Amenity模型:

var Amenity = exports.Amenity = Bookshelf.Model.extend({
  tableName: 'amenity'
});

3)使用Bookshelf添加酒店模型,并使用belongsToMany引用Amenity:

var Hotel = exports.Hotel = Bookshelf.Model.extend({
  tableName: 'hotel',
  nearbyAmenities: function() {
    return this.belongsToMany(Amenity, 'hotel_amenity')
    .withPivot('distance_km')
    .query('orderBy', 'distance_km', 'asc')
    .query('limit', 10);
  }
});

在取酒店时不要忘记使用withRelated