gpt4 book ai didi

javascript - 使用 Knex.js 创建嵌套返回模型

转载 作者:搜寻专家 更新时间:2023-11-01 00:37:09 27 4
gpt4 key购买 nike

我正在使用 Knex.js 在 Hapi.js 路由中查询 MySQL 数据库。以下代码有效,但需要嵌套查询:

{
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 匹配的嵌套对象,这样我就没有嵌套的 promise ?

最佳答案

简短回答:否。

使用 Knex,您可以像使用 SQL 一样检索数据,它是基于记录的,而不是基于对象的,因此最接近的方法是使用连接来允许仅执行一次选择来检索单个数组具有元素:食谱、指南、配料。这将重复每种成分的配方和指南,您可以通过使用嵌套对象来避免这种情况。 (有关此示例,请参阅下面@Fazal 的回答。)

作为另一种选择,您可以将配料存储为配方表中的“blob”字段,但我认为 MySQL 不允许您创建数组字段,因此在检索数据时,您必须将字段转换为数组。并在将其更新到表中之前将其从 Array 转换。如:storableData = JSON.stringify(arrayData)arrayData = JSON.parse(storableData)

不过,我还建议您采取其他一些措施来帮助您改进代码。 (是的,我知道,这不是真正的问题):

  1. 将路由功能与数据处理分开。
  2. 此外,将数据操作功能与检索功能分开。
  3. 使用 throw 和 .catch 创建和处理不成功的响应。

路由、数据检索、数据操作的分离使得测试、调试和 future 的理解更容易,因为每个功能都有更原子的目的。

Throwing/.catching 不成功的过程条件允许您在路由器响应处理中放置(大部分时间)单个 .catch(Hapi.js 甚至可以执行此 .catch),从而使更全面的错误处理变得更加简单给你???)。

此外,请参阅我为记录错误而添加的其他 .catch.on('query-error'。您可能有不同的记录机制使用而不是控制台。我使用 Winston。请注意 .on('query-error' 不是 .catch。仍然会有一个 Error() 被抛出,并且必须被处理在某个地方,这只会为您提供有关故障源附近故障的良好信息。

(抱歉,以下代码未经测试)

path: '/recipes',
method: 'GET',
handler: (req, res) => {
return getRecipeNIngredients()
.then((recipes) => {
res({
count: recipes.length,
data: recipes
});
})
.catch((ex) => {
res({
error: true,
errMessage: ex.message
});
});
};

function getRecipeNIngredients() {
let recipes = null;
return getRecipes()
.then((recipeList) => {
recipes = recipeList;
const recipeGuids = recipes.map(recipe => recipe.guid);
recipes.forEach(r => r.ingredients = []);
return getIngredients(recipeGuids);
})
.then((ingredients) => {
recipes.forEach(r => {
ingredients.forEach(i => {
if (i.recipe === r.guid) {
r.ingredients.push(i);
}
});
});
return recipes;
})
.catch((ex) => {
console.log(".getRecipeNIngredients ERROR ex:",ex); // log and rethrow error.
throw ex;
});
};

function getRecipes() {
return Knex.from('recipes')
// .innerJoin('ingredients', 'recipes.guid', 'ingredients.recipe')
.select()
.orderBy('rating', 'desc')
.limit(10)
.on('query-error', function(ex, obj) {
console.log("KNEX getRecipes query-error ex:", ex, "obj:", obj);
})
.then((recipes) => {
if (!recipes || recipes.length === 0) {
throw new Error('no recipes found')
}
})
};
function getIngredients(recipeGuids) {
return Knex.from('ingredients')
.whereIn('recipe', recipeGuids)
.select()
.on('query-error', function(ex, obj) {
console.log("KNEX getIngredients query-error ex:", ex, "obj:", obj);
})
};

我希望这是有用的!加里。

关于javascript - 使用 Knex.js 创建嵌套返回模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47503627/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com