Javascript 使用Knex.js创建嵌套的返回模型
我使用Knex.js以Hapi.js路由查询MySQL数据库。以下代码可以工作,但需要嵌套查询:Javascript 使用Knex.js创建嵌套的返回模型,javascript,node.js,knex.js,hapi.js,Javascript,Node.js,Knex.js,Hapi.js,我使用Knex.js以Hapi.js路由查询MySQL数据库。以下代码可以工作,但需要嵌套查询: { path: '/recipes', method: 'GET', handler: (req, res) => { const getOperation = Knex.from('recipes') // .innerJoin('ingredients', 'recipes.guid', 'ingredients.recipe')
{
path: '/recipes',
method: 'GET',
handler: (req, res) => {
const getOperation = Knex.from('recipes')
// .innerJoin('ingredients', 'recipes.guid', 'ingredients.recipe')
.select()
.orderBy('rating', 'desc')
.limit(10)
.then((recipes) => {
if (!recipes || recipes.length === 0) {
res({
error: true,
errMessage: 'no recipes found'
});
}
const recipeGuids = recipes.map(recipe => recipe.guid);
recipes.forEach(r => r.ingredients = []);
const getOperation2 = Knex.from('ingredients')
.whereIn('recipe', recipeGuids)
.select()
.then((ingredients) => {
recipes.forEach(r => {
ingredients.forEach(i => {
if (i.recipe === r.guid) {
r.ingredients.push(i);
}
});
});
res({
count: recipes.length,
data: recipes
});
});
});
}
}
有没有办法用Knex.js创建一个返回模型,该模型具有与父级id/guid匹配的嵌套对象,这样我就不会有嵌套的承诺?简短回答:没有
使用Knex,您可以像使用SQL一样检索数据,SQL是基于记录的,而不是基于对象的,因此最接近的方法是使用联接,只允许执行单个选择来检索包含以下元素的单个数组:配方、GUID和配料。这将为每个成分重复配方和guid,通过使用嵌套对象可以避免这种情况。(请参见下面@Fazal的答案,以了解这方面的示例。)
作为另一种选择,您可以将配料存储为配方表中的“blob”字段,但我认为MySQL不允许您创建数组字段,因此在检索数据时,您必须将字段转换为数组。并在将其更新到表中之前将其从数组中转换。比如:storableData=JSON.stringify(arrayData)
和arrayData=JSON.parse(storableData)
不过,我还建议做一些其他事情来帮助您改进代码。(是的,我知道,这不是真正的问题):
.catch
和.on('query-error'
)。您可能需要使用不同的日志机制,而不是控制台。我使用Winston。请注意,.on('query-error'
不是.catch。仍然会有错误()这是抛出的,并且必须在某个地方处理,这将为您提供有关源附近的故障的良好信息
(对不起,下面的代码未经测试)
我希望这是有用的!
Gary。您可以轻松避免嵌套查询。只需将子查询用作-
knex.select('*')
.from(function () {
this.select('*').from('recipes').limit(10).as('recipes'); // limit here
})
.leftJoin('ingredients', 'ingredients.recipe_id', 'recipes.guid')
.then((rec) => {
console.log(rec);
})
请参阅..只有几行代码。我创建了一个库,它返回嵌套对象,即使它有typescript的类型
import*作为n从“嵌套的knex”导入;
n、 排列(
n、 类型({
id:n.number(“recipe.id”,{id:true}),
标题:n.string(“recipe.title”),
成分:n(
n、 类型({
id:n.number(“components.id”,{id:true}),
标题:n.string(“配料名称”)
})
)
})
)
.withQuery(
捏
.来自(“食谱”)
.innerJoin(“配料”、“配方.guid”、“配料.配方”)
.选择()
.orderBy(“评级”、“说明”)
.限额(10)
)
.然后(配方=>{});
所以食谱甚至有不同的类型
knex.select('*')
.from(function () {
this.select('*').from('recipes').limit(10).as('recipes'); // limit here
})
.leftJoin('ingredients', 'ingredients.recipe_id', 'recipes.guid')
.then((rec) => {
console.log(rec);
})