Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何正确映射sequelize.js中关系的属性?_Sequelize.js_Postgresql_Javascript_Node.js - Fatal编程技术网

如何正确映射sequelize.js中关系的属性?

如何正确映射sequelize.js中关系的属性?,sequelize.js,postgresql,javascript,node.js,Sequelize.js,Postgresql,Javascript,Node.js,我正在创建一个食谱数据库(通常称为烹饪书),在这里,我需要在配料和食谱之间建立多对多的关系,并且我正在结合使用 当一种成分被添加到配方中时,我需要声明进入配方的该成分的正确数量 我已声明(简化示例) 我的问题是,当我的一个REST端点返回数据时,数据是如何返回的 router.get('/recipes', function(req, res) { Recipe.findAll({ include: [{ model: Ingredient,

我正在创建一个食谱数据库(通常称为烹饪书),在这里,我需要在配料和食谱之间建立多对多的关系,并且我正在结合使用

当一种成分被添加到配方中时,我需要声明进入配方的该成分的正确数量

我已声明(简化示例)

我的问题是,当我的一个REST端点返回数据时,数据是如何返回的

router.get('/recipes', function(req, res) {
    Recipe.findAll({
        include: [{
            model: Ingredient,
            as: 'ingredients'
         }]
    }).then(function(r) {
        return res.status(200).json(r[0].toJSON());
    })
});
发送到客户端的结果JSON如下所示(省略时间戳):

而我想要的只是

{
  "id": 1,
  "name": "Carrots",
  "ingredients": [
    {
      "id": 1,
      "name": "carrot",
      "amount": 12,
    }
  ]
}
也就是说,我希望关系表中的
amount
字段包含在结果中,而不是整个
RecipeCredit
对象中

sequelize生成的数据库如下所示:

Ingredients id name 1 carrot Recipes id name 1 Carrots RecipeIngredients amount RecipeId IngredientId 12 1 1
include: [{
    model: Ingredient,
    as: 'ingredients',
    attributes: []
 }]
router.get('/recipes', function(req, res) {
    Recipe.findAll({
        include: [{
            model: Ingredient,
            as: 'ingredients',
            through: {
                attributes: ['amount']
            }
         }]
    }).then(function(recipes) {
        return recipes[0].toJSON();
    }).then(function(recipe) {
        recipe.ingredients = recipe.ingredients.map(function(i) {
            i.amount = i.RecipeIngredient.amount;
            delete i.RecipeIngredient;
            return i;
        });
        return recipe;
    }).then(function(recipe) {
        return res.status(200).json(recipe);
    });
});
但是将
['amount']
['RecipeCredit.amount']
设置为属性值会引发如下错误

未处理的拒绝SequelizeDatabaseError:列Components.RecipeInCredit.amount不存在


显然,我可以在JS中使用
.map
修复这个问题,但肯定有办法让sequelize为我完成这项工作

我查看了文档,但找不到任何可以让我将联接表的属性合并到结果中的内容,因此看起来我不得不这样做:

Ingredients id name 1 carrot Recipes id name 1 Carrots RecipeIngredients amount RecipeId IngredientId 12 1 1
include: [{
    model: Ingredient,
    as: 'ingredients',
    attributes: []
 }]
router.get('/recipes', function(req, res) {
    Recipe.findAll({
        include: [{
            model: Ingredient,
            as: 'ingredients',
            through: {
                attributes: ['amount']
            }
         }]
    }).then(function(recipes) {
        return recipes[0].toJSON();
    }).then(function(recipe) {
        recipe.ingredients = recipe.ingredients.map(function(i) {
            i.amount = i.RecipeIngredient.amount;
            delete i.RecipeIngredient;
            return i;
        });
        return recipe;
    }).then(function(recipe) {
        return res.status(200).json(recipe);
    });
});
通过将
传递到
包含
可以从联接表中筛选出要包含的属性,但在我的一生中,我找不到让sequelize为我合并它的方法


上面的代码将返回我想要的输出,但是增加了循环成分列表的开销,这不是我想要的,但是除非有人提出更好的解决方案,否则我看不到其他方法来实现这一点。

您可以使用sequelize.literal。使用配方的配料别名,您可以编写如下内容。我不知道这是不是正确的方法

我使用sqlite3进行了测试。收到的别名为“ir”的结果为

请参阅此处的完整代码


这一次我已经晚了很多,但是我看到它被浏览了很多次,所以这里是我关于如何合并的答案 属性

这本书中有一些随机的例子

router.get('/recipes', function(req, res) {
Recipe.findAll({
    include: [{
        model: Ingredient,
        as: 'ingredients',
        through: {
            attributes: ['amount']
        }
     }]
})
.then(docs =>{
    const response = {
        Deal: docs.map(doc =>{
            return{
                cakeRecipe:doc.recipe1,
                CokkieRecipe:doc.recipe2,
                Apples:doc.ingredients.recipe1ingredient
                spices:[
                    {
                     sugar:doc.ingredients.spice1,
                     salt:doc.ingredients.spice2
                    }
                ]

            }
        })
    }

})
res.status(200).json(response)
})

router.get('/recipes', function(req, res) {
Recipe.findAll({
    include: [{
        model: Ingredient,
        as: 'ingredients',
        through: {
            attributes: ['amount']
        }
     }]
})
.then(docs =>{
    const response = {
        Deal: docs.map(doc =>{
            return{
                cakeRecipe:doc.recipe1,
                CokkieRecipe:doc.recipe2,
                Apples:doc.ingredients.recipe1ingredient
                spices:[
                    {
                     sugar:doc.ingredients.spice1,
                     salt:doc.ingredients.spice2
                    }
                ]

            }
        })
    }

})
res.status(200).json(response)