Node.js पर Sequelize का उपयोग करके शामिल होने की क्वेरी कैसे करें


104

मैं अगली कड़ी ORM का उपयोग कर रहा हूं; सब कुछ महान और साफ है, लेकिन मुझे एक समस्या थी जब मैं इसे joinप्रश्नों के साथ उपयोग करता हूं । मेरे पास दो मॉडल हैं: उपयोगकर्ता और पोस्ट।

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 शैली का उपयोग करने के लिए कोड कैसे बदल सकता हूं?

जवाबों:


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

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

जो आपको देंगे

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`;

आपके द्वारा पोस्ट की गई तुलना में उपरोक्त क्वेरी थोड़ी जटिल लग सकती है, लेकिन यह जो करती है वह मूल रूप से उपयोगकर्ताओं की तालिका के सभी स्तंभों को अलग-अलग कर रही है, यह सुनिश्चित करने के लिए कि उन्हें सही मॉडल में रखा गया है जब वे लौटें और पोस्ट मॉडल के साथ मिश्रित न हों

इसके अलावा, आप देखेंगे कि यह दो तालिकाओं से चयन करने के बजाय एक JOIN करता है, लेकिन परिणाम समान होना चाहिए

आगे की पढाई:


7
क्या होगा यदि मैं केवल उन उपयोगकर्ताओं में शामिल होना चाहता हूं जो 1984 में पैदा हुए हैं? एसक्यूएल में मैं करूंगा:SELECT * FROM posts JOIN users ON users.id = posts.user_id WHERE users.year_birth = 1984
इवाज़ारु

1
सभी लिंक मृत हैं :-(
मानवल

1
क्या वह प्रश्न कभी उत्तर वाले प्रश्न में पोस्ट किया गया था?
theptrk

1
क्या हमें दोनों की आवश्यकता है या एक ही पर्याप्त है: User.hasMany (पोस्ट, {ForeignKey: 'user_id'}) Post.belongsTo (उपयोगकर्ता, {विदेशीकेय: 'user_id'})
एंटीवेन

1
@antew जब आप कॉल User.hasMany(Post)करते हैं तो आप उपयोगकर्ता ऑब्जेक्ट में विधियाँ / विशेषताएँ जोड़ते हैं, और जब आप कॉल Post.belongsTo(User)करते हैं तो आप पोस्ट क्लास में विधियाँ जोड़ते हैं। यदि आप हमेशा एक दिशा से कॉल कर रहे हैं (उदा। User.getPosts ()) तो आपको पोस्ट ऑब्जेक्ट में कुछ भी जोड़ने की आवश्यकता नहीं है। लेकिन दोनों तरफ के तरीकों का होना अच्छा है।
रयान

170

जबकि स्वीकृत उत्तर तकनीकी रूप से गलत नहीं है, यह मूल प्रश्न का उत्तर नहीं देता है और न ही टिप्पणियों में अनुवर्ती प्रश्न है, जो कि मैं यहां खोज रहा था। लेकिन मुझे यह समझ में आया, इसलिए यहां चला गया।

यदि आप उन सभी पोस्ट को ढूंढना चाहते हैं, जिनमें उपयोगकर्ता (और केवल वही हैं जिनके पास उपयोगकर्ता हैं) जहां 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 => {
  /* ... */
});

सच्चे में स्थापित करना एक आंतरिक जुड़ाव पैदा करने की कुंजी है। यदि आप एक बाईं ओर से जुड़ना चाहते हैं (जहां आपको सभी पोस्ट मिलते हैं, भले ही कोई उपयोगकर्ता जुड़ा हुआ है) तो झूठे के लिए आवश्यक परिवर्तन करें, या इसे छोड़ दें क्योंकि यह डिफ़ॉल्ट है:

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

यदि आप उन सभी पोस्टों को खोजना चाहते हैं, जिनका जन्म वर्ष 1984 है, तो आप चाहते हैं:

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

ध्यान दें कि जैसे ही आप एक क्लॉज जोड़ते हैं, डिफ़ॉल्ट रूप से आवश्यक है।

यदि आप सभी पोस्ट चाहते हैं, तो इस बात की परवाह किए बिना कि कोई उपयोगकर्ता संलग्न है, लेकिन यदि कोई उपयोगकर्ता है, तो केवल 1984 में पैदा हुए लोग हैं, तो आवश्यक फ़ील्ड को वापस जोड़ें:

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

यदि आप सभी पोस्ट चाहते हैं जहां नाम "सनशाइन" है और केवल अगर यह 1984 में पैदा हुए उपयोगकर्ता का है, तो आप ऐसा करेंगे:

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

यदि आप सभी पोस्ट चाहते हैं, जहां नाम "सनशाइन" है और केवल अगर यह उसी उपयोगकर्ता से संबंधित है जो उसी वर्ष में पैदा हुआ था जो पोस्ट पर पोस्ट_ऑयर विशेषता से मेल खाता है, तो आप ऐसा करेंगे:

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

मुझे पता है, इसका कोई मतलब नहीं है कि कोई व्यक्ति जिस वर्ष पैदा हुआ था, उस वर्ष के लिए एक पोस्ट करेगा, लेकिन यह सिर्फ एक उदाहरण है - इसके साथ जाओ। :)

मैंने इस डॉक्टर से इसका (ज्यादातर) पता लगाया:


9
बहुत-बहुत धन्यवाद, यह उपयोगी था
Neo

6
हाँ, महान जवाब
duxfox--

तो क्या posts.user_id = users.idआपके अगली कड़ी में प्रतिनिधित्व करता है? धन्यवाद
hanzichi

5
यह उत्तर इतना विस्तृत है कि इसे सीक्वेलाइज़ के डॉक में जोड़ा जाना चाहिए
जियोर्जियो

2
ट्यूटोरियल का एक बड़ा टुकड़ा जिसकी मुझे तलाश है। बहुत कुछ
एंड्रयू रेयान


2

मेरे मामले में मैंने निम्नलिखित कार्य किया। UserMaster userId में PK है और UserAccess userId में UserMaster का FK है

UserAccess.belongsTo(UserMaster,{foreignKey: 'userId'});
UserMaster.hasMany(UserAccess,{foreignKey : 'userId'});
var userData = await UserMaster.findAll({include: [UserAccess]});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.