如何在 KnexJS + bookshelf 中查询嵌套外键
How to query on nested foreign keys in KnexJS + bookshelf
我将 knexJS 和书架 ORM 用于我的 nodejs 应用程序。问题是,当给出记录 ID 时,我需要查询获取其 "great-grandchildren" 记录的列表。目标 table 中有数千条记录,因此页码和大小也应该作为参数传递,我需要通过查询对其进行排序。获取所有记录后进行过滤不是解决方案。
让我解释一下模型之间的关系。
// MenuItem model
module.exports = (Model, models) => {
return Model.extend({
tableName: 'menu_items',
menu_day() {
return this.belongsTo(models.MenuDay);
},
});
};
这是 MenuItem
型号,我要为其获取列表。如您所见,它通过外键与 MenuDay
模型相关。
// MenuDay model
module.exports = (Model, models) => {
return Model.extend({
tableName: 'menu_days',
menu_items() {
return this.hasMany(models.MenuItem);
},
menu() {
return this.belongsTo(models.Menu);
}
});
};
MenuDay
模型通过外键与 Menu
模型相关。
// Menu model
module.exports = (Model, models) => {
return Model.extend({
tableName: 'menus',
menu_days() {
return this.hasMany(models.MenuDay);
},
restaurant() {
return this.belongsTo(models.Restaurant);
}
});
};
Menu
模型与 Restaurant
相关,餐厅 ID 只是作为该位置的输入。
// Restaurant model
module.exports = (Model, models) => {
return Model.extend({
tableName: 'restaurants',
menus() {
return this.hasMany(models.Menu);
}
});
};
我尝试了很多解决方案来解决这个问题,但我在这个问题上浪费了几天时间。
不管是什么,任何帮助将不胜感激!你会救我的命。
您可以使用 fetch()
的 withRelated
选项:
new Restaurant({id: 1}).fetch({
withRelated: ['menus.menu_days.menu_items']
}).then(restaurant => {
const menus = restaurant.related('menus')
const menuDays = menus.related('menu_days')
const menuItems = menuDays.related('menu_items')
})
我只能使用 Knex 自己解决这个问题,不能使用 Bookshelf。
knex.raw(`
SELECT * FROM menu_items WHERE menu_day_id IN (
SELECT id FROM menu_days WHERE menu_id IN (
SELECT id FROM menus WHERE restaurant_id = ?
)
) LIMIT ? OFFSET ?
`, [restaurantId, limit, (page - 1) * limit])
.then(res => {
const menuItems = res.rows;
});
我将 knexJS 和书架 ORM 用于我的 nodejs 应用程序。问题是,当给出记录 ID 时,我需要查询获取其 "great-grandchildren" 记录的列表。目标 table 中有数千条记录,因此页码和大小也应该作为参数传递,我需要通过查询对其进行排序。获取所有记录后进行过滤不是解决方案。
让我解释一下模型之间的关系。
// MenuItem model
module.exports = (Model, models) => {
return Model.extend({
tableName: 'menu_items',
menu_day() {
return this.belongsTo(models.MenuDay);
},
});
};
这是 MenuItem
型号,我要为其获取列表。如您所见,它通过外键与 MenuDay
模型相关。
// MenuDay model
module.exports = (Model, models) => {
return Model.extend({
tableName: 'menu_days',
menu_items() {
return this.hasMany(models.MenuItem);
},
menu() {
return this.belongsTo(models.Menu);
}
});
};
MenuDay
模型通过外键与 Menu
模型相关。
// Menu model
module.exports = (Model, models) => {
return Model.extend({
tableName: 'menus',
menu_days() {
return this.hasMany(models.MenuDay);
},
restaurant() {
return this.belongsTo(models.Restaurant);
}
});
};
Menu
模型与 Restaurant
相关,餐厅 ID 只是作为该位置的输入。
// Restaurant model
module.exports = (Model, models) => {
return Model.extend({
tableName: 'restaurants',
menus() {
return this.hasMany(models.Menu);
}
});
};
我尝试了很多解决方案来解决这个问题,但我在这个问题上浪费了几天时间。 不管是什么,任何帮助将不胜感激!你会救我的命。
您可以使用 fetch()
的 withRelated
选项:
new Restaurant({id: 1}).fetch({
withRelated: ['menus.menu_days.menu_items']
}).then(restaurant => {
const menus = restaurant.related('menus')
const menuDays = menus.related('menu_days')
const menuItems = menuDays.related('menu_items')
})
我只能使用 Knex 自己解决这个问题,不能使用 Bookshelf。
knex.raw(`
SELECT * FROM menu_items WHERE menu_day_id IN (
SELECT id FROM menu_days WHERE menu_id IN (
SELECT id FROM menus WHERE restaurant_id = ?
)
) LIMIT ? OFFSET ?
`, [restaurantId, limit, (page - 1) * limit])
.then(res => {
const menuItems = res.rows;
});