2013-12-08 4 views
35

ORM을 sequelize로 사용하고 있습니다. 모든 것이 훌륭하고 깨끗하지만, join 쿼리와 함께 사용할 때 문제가있었습니다. 두 가지 모델, 즉 사용자와 게시물이 있습니다.nodejs에서 sequelize를 사용하여 join querys를 작성하는 방법

var User = db.seq.define('User',{ 
    username: { type: db.Sequelize.STRING}, 
    email: { type: db.Sequelize.STRING}, 
    password: { type: db.Sequelize.STRING}, 
    sex : { type: db.Sequelize.INTEGER}, 
    day_birth: { type: db.Sequelize.INTEGER}, 
    month_birth: { type: db.Sequelize.INTEGER}, 
    year_birth: { type: db.Sequelize.INTEGER} 

}); 

User.sync().success(function(){ 
    console.log("table created") 
}).error(function(error){ 
    console.log(err); 
}) 


var Post = db.seq.define("Post",{ 
    body: { type: db.Sequelize.TEXT }, 
    user_id: { type: db.Sequelize.INTEGER}, 
    likes: { type: db.Sequelize.INTEGER, defaultValue: 0 }, 

}); 

Post.sync().success(function(){ 
    console.log("table created") 
}).error(function(error){ 
    console.log(err); 
}) 

나는 그것을 만든 사용자의 정보로 게시물에 응답하는 쿼리를 원합니다. 원시 쿼리에서 나는이 얻을 :

db.seq.query('SELECT * FROM posts, users WHERE posts.user_id = users.id ').success(function(rows){ 
      res.json(rows); 
     }); 

내 질문은 어떻게 SQL 쿼리 대신 ORM 스타일을 사용하도록 코드를 변경할 수 있습니까? 쿼리가 위의 당신이 무엇을 게시에 비해 조금 복잡하게 보일 수 있습니다 당신에게

SELECT 
    `posts`.*, 
    `users`.`username` AS `users.username`, `users`.`email` AS `users.email`, 
    `users`.`password` AS `users.password`, `users`.`sex` AS `users.sex`, 
    `users`.`day_birth` AS `users.day_birth`, 
    `users`.`month_birth` AS `users.month_birth`, 
    `users`.`year_birth` AS `users.year_birth`, `users`.`id` AS `users.id`, 
    `users`.`createdAt` AS `users.createdAt`, 
    `users`.`updatedAt` AS `users.updatedAt` 
FROM `posts` 
    LEFT OUTER JOIN `users` AS `users` ON `users`.`id` = `posts`.`user_id`; 

를 제공하지만 기본적으로 그냥 확인하기 위해 사용자 테이블의 모든 열을 앨리어싱 그것이 무엇을하는 것은

답변

51
User.hasMany(Post, {foreignKey: 'user_id'}) 
Post.belongsTo(User, {foreignKey: 'user_id'}) 

Post.find({ where: { ...}, include: [User]}) 

그들이 리턴 된 모델과 포스트 모델이 섞이지 않았을 때 올바른 모델에 배치됩니다.

두 테이블에서 선택하는 대신 JOIN이 발생하지만 결과는 동일해야합니다.

추가 읽기 :

+0

감사 남자. –

+6

1984 년 출생 한 사용자 만 가입하려면 어떻게해야합니까? SQL에서 나는 다음과 같이 할 것이다 :'SELECT * FROM posts users on user.id = posts.user_id where users.year_birth = 1984' – Iwazaru

+0

@Iwazaru 답이 너무 길어서 의견에 맞지 않을 경우 새로운 질문을 열어주세요 –

0
Model1.belongsTo(Model2, { as: 'alias' }) 

Model1.findAll({include: [{model: Model2 , as: 'alias' }]},{raw: true}).success(onSuccess).error(onError); 
7

허용 대답은 기술적으로 잘못된 것은 아니지만, 그것은 원래의 질문이나 답변을하지 않습니다 코멘트에서 질문을 따라해라. 내가 여기에서 찾으러 왔던 것이었다. 그러나 나는 그것을 알아 냈다. 그래서 여기에 간다.

당신이 SQL은 다음과 같이 보일 것이다 사용자 (사용자가있는 경우에만 사람)가 모든 게시물을 찾으려면 : 의미 영업의 원래 SQL과 같은 일이

SELECT * FROM posts INNER JOIN users ON posts.user_id = users.id 

:

SELECT * FROM posts, users WHERE posts.user_id = users.id 

다음이 당신이 원하는 무엇인가 :

Posts.findAll({ 
    include: [{ 
    model: User, 
    required: true 
    }] 
}).then(posts => { 
    /* ... */ 
}); 

설정은 그럴 필요하는 데 필요한 ue는 내부 조인을 만드는 열쇠입니다. 모든 찾으려면

Posts.findAll({ 
    include: [{ 
    model: User, 
// required: false 
    }] 
}).then(posts => { 
    /* ... */ 
}); 

: 그 기본이기 때문에 당신은 왼쪽 외부 (관계없이 연결된 사용자가 있는지 여부의 모든 게시물받을 곳)를 false로 요구 된 변경에 가입하거나 생략 할 원하는 경우 그의 출생 1984 년에 사용자에 속하는 게시물, 당신이 원하는 것 : 필요

Posts.findAll({ 
    include: [{ 
    model: User, 
    where: {year_birth: 1984} 
    }] 
}).then(posts => { 
    /* ... */ 
}); 

참고 즉시 당신이 where 절을 추가 할 때 기본적으로 사실이다.모든 원하는 경우

Posts.findAll({ 
    include: [{ 
    model: User, 
    where: {year_birth: 1984} 
    required: false, 
    }] 
}).then(posts => { 
    /* ... */ 
}); 

: 모든 게시물을 원하는 경우에 사용자가있는 경우

에 관계없이 연결된 사용자가 있는지 여부의 그러나 1984 년에 태어난 유일한 사람은 그 다음에 필요한 필드를 다시 추가 그것은 1984 년에 태어났다 사용자에 속하는 경우 이름과 "선샤인"입니다 게시물 만이 할 거라고 :

Posts.findAll({ 
    where: {name: "Sunshine"}, 
    include: [{ 
    model: User, 
    where: {year_birth: 1984} 
    }] 
}).then(posts => { 
    /* ... */ 
}); 

당신이하고있는 경우에만 이름이 "선샤인"모든 게시물을 원하는 경우 같은 연도에 태어난 사용자가 속한 post_year 속성과 일치합니다. 포스트, 당신은이 작업을 수행 할 것 :

Posts.findAll({ 
    where: {name: "Sunshine"}, 
    include: [{ 
    model: User, 
    where: ["year_birth = post_year"] 
    }] 
}).then(posts => { 
    /* ... */ 
}); 

내가 아는 한, 그것은 누군가가 게시물 그들이 태어난 해 할 것이 이해가되지 않지만, 그냥 예 - 그것은과 함께 할 것입니다. :)

나는이 문서에서 (대부분)이 알아 낸 : 위대한 작품을

관련 문제