अनुक्रमित करें, इकाई को सादे वस्तु में बदलें


95

मैं जावास्क्रिप्ट, और तेजस्वी से बहुत परिचित नहीं हूं, क्योंकि मैं ऑब्जेक्ट में नई प्रॉपर्टी नहीं जोड़ सकता, जो कि ORM नाम Sequelize.js का उपयोग करके डेटाबेस से प्राप्त हुई है।

इससे बचने के लिए, मैं इस हैक का उपयोग करता हूं:

db.Sensors.findAll({
    where: {
        nodeid: node.nodeid
    }
}).success(function (sensors) {
        var nodedata = JSON.parse(JSON.stringify(node)); // this is my trick
        nodedata.sensors = sensors;
        nodesensors.push(nodedata);
        response.json(nodesensors);
});

तो, आम तौर पर नए गुणों को वस्तु में जोड़ने का क्या तरीका है।

यदि यह मदद कर सकता है, तो मैं सीरीज़-पोस्टग्रेज़ संस्करण 2.0.x का उपयोग करता हूं।

युपीडी। console.log (नोड):

{ dataValues: 
   { nodeid: 'NodeId',
     name: 'NameHere',
     altname: 'Test9',
     longname: '',
     latitude: 30,
     longitude: -10,
     networkid: 'NetworkId',
     farmid: '5',
     lastheard: Mon Dec 09 2013 04:04:40 GMT+0300 (FET),
     id: 9,
     createdAt: Tue Dec 03 2013 01:29:09 GMT+0300 (FET),
     updatedAt: Sun Feb 23 2014 01:07:14 GMT+0300 (FET) },
  __options: 
   { timestamps: true,
     createdAt: 'createdAt',
     updatedAt: 'updatedAt',
     deletedAt: 'deletedAt',
     touchedAt: 'touchedAt',
     instanceMethods: {},
     classMethods: {},
     validate: {},
     freezeTableName: false,
     underscored: false,
     syncOnAssociation: true,
     paranoid: false,
     whereCollection: { farmid: 5, networkid: 'NetworkId' },
     schema: null,
     schemaDelimiter: '',
     language: 'en',
     defaultScope: null,
     scopes: null,
     hooks: { beforeCreate: [], afterCreate: [] },
     omitNull: false,
     hasPrimaryKeys: false },
  hasPrimaryKeys: false,
  selectedValues: 
   { nodeid: 'NodeId',
     name: 'NameHere',
     longname: '',
     latitude: 30,
     longitude: -110,
     networkid: 'NetworkId',
     farmid: '5',
     lastheard: Mon Dec 09 2013 04:04:40 GMT+0300 (FET),
     id: 9,
     createdAt: Tue Dec 03 2013 01:29:09 GMT+0300 (FET),
     updatedAt: Sun Feb 23 2014 01:07:14 GMT+0300 (FET),
     altname: 'Test9' },
  __eagerlyLoadedAssociations: [],
  isDirty: false,
  isNewRecord: false,
  daoFactoryName: 'Nodes',
  daoFactory: 
   { options: 
      { timestamps: true,
        createdAt: 'createdAt',
        updatedAt: 'updatedAt',
        deletedAt: 'deletedAt',
        touchedAt: 'touchedAt',
        instanceMethods: {},
        classMethods: {},
        validate: {},
        freezeTableName: false,
        underscored: false,
        syncOnAssociation: true,
        paranoid: false,
        whereCollection: [Object],
        schema: null,
        schemaDelimiter: '',
        language: 'en',
        defaultScope: null,
        scopes: null,
        hooks: [Object],
        omitNull: false,
        hasPrimaryKeys: false },
     name: 'Nodes',
     tableName: 'Nodes',
     rawAttributes: 
      { nodeid: [Object],
        name: [Object],
        altname: [Object],
        longname: [Object],
        latitude: [Object],
        longitude: [Object],
        networkid: [Object],
        farmid: [Object],
        lastheard: [Object],
        id: [Object],
        createdAt: [Object],
        updatedAt: [Object] },
     daoFactoryManager: { daos: [Object], sequelize: [Object] },
     associations: {},
     scopeObj: {},
     primaryKeys: {},
     primaryKeyCount: 0,
     hasPrimaryKeys: false,
     autoIncrementField: 'id',
     DAO: { [Function] super_: [Function] } } }

मुझे लगता है कि आगे, आपको क्या लगता है: "ठीक है, यह आसान है, बस अपनी संपत्ति को डेटावैल्यूज में जोड़ें।"

node.selectedValues.sensors = sensors;
node.dataValues.sensors = sensors;

मैं इस पंक्तियों को जोड़ता हूं, और यह काम नहीं करता है


nodeपारंपरिक वस्तु नहीं होनी चाहिए। शायद यह एक बफर है? console.log(node);आपकी ट्रिक लाइन से पहले क्या कहता है?
केविन रेली

कृपया पोस्ट अपडेट देखें।
रुस्लान

जवाबों:


42

अगर मैं आपको सही कर दूं, तो आप sensorsसंग्रह को इसमें जोड़ना चाहते हैं node। तुम दोनों मॉडलों के बीच एक मानचित्रण है, तो आप या तो उपयोग कर सकते हैं includeकार्यक्षमता यहाँ समझाया या valuesगेटर हर मामले पर परिभाषित किया। आप उसके लिए डॉक्स यहां पा सकते हैं ।

उत्तरार्द्ध का उपयोग इस तरह किया जा सकता है:

db.Sensors.findAll({
  where: {
    nodeid: node.nodeid
  }
}).success(function (sensors) {
  var nodedata = node.values;

  nodedata.sensors = sensors.map(function(sensor){ return sensor.values });
  // or
  nodedata.sensors = sensors.map(function(sensor){ return sensor.toJSON() });

  nodesensors.push(nodedata);
  response.json(nodesensors);
});

मौका है कि nodedata.sensors = sensorsकाम भी कर सकता है।


2
धन्यवाद, सभी की जरूरत है: नोड। अंतराल:
रुस्लान

147

आप {raw: true}कच्चे परिणाम वापस करने के लिए क्वेरी विकल्पों का उपयोग कर सकते हैं । आपकी क्वेरी निम्नानुसार होनी चाहिए:

db.Sensors.findAll({
  where: {
    nodeid: node.nodeid
  },
  raw: true,
})

यह भी कि अगर आपके साथ जुड़ाव includeहो जाता है तो चपटा हो जाता है। तो, हम दूसरे पैरामीटर का उपयोग कर सकते हैंnest:true

db.Sensors.findAll({
  where: {
    nodeid: node.nodeid
  },
  raw: true,
  nest: true,
})

32
"कच्चा: सच" किसी भी तरह से संबंधित मॉडल द्वारा इंजेक्ट किए गए सरणी को समतल कर देगा। मेरे आसपास अब तक का एकमात्र काम केवल कॉन्फ़िगर करना है = JSON.parse (JSON.stringify (configs));
सोइची हयाशी

1
स्वीकृत उत्तर की तुलना में यह सरल और बेहतर दृष्टिकोण है। धन्यवाद
जहर

1
@SoichiHayashi वास्तव में, इसके विपरीत जब आप इसके बारे में सोचते हैं ...;) कच्चे के बिना: सच है, किसी भी तरह से अनुक्रमित वस्तुओं में परिणाम को उजागर करता है। Sql क्वेरी से परिणाम पहले से ही चपटा है। मैंने फ्लैट परिणाम प्राप्त करने के लिए इसे कुछ बार उपयोगी पाया है ... इस उत्तर के लिए +1।
पीआरएस

4
@SoichiHayashi कच्चे लेकिन नेस्टेड परिणाम प्राप्त करने के लिए, आप nest: trueके साथ उपयोग कर सकते हैं raw: true
अवधी

किसी भी विचार को raw:trueवैश्विक सेटिंग के रूप में कैसे पारित किया जाए, इसलिए इसे हर प्रश्न को पारित करने की आवश्यकता नहीं है? धन्यवाद
codebot

109

हाल ही में इस सवाल पर आने वालों के लिए, .valuesसीक्वेलाइज 3.0.0 के रूप में चित्रित किया गया है। .get()सादे जावास्क्रिप्ट ऑब्जेक्ट को प्राप्त करने के बजाय उपयोग करें । तो उपरोक्त कोड में बदल जाएगा:

var nodedata = node.get({ plain: true });

यहां से डॉक्स को अलग करें


6
अगर मैं गलत हूं तो मुझे सुधारो - लेकिन मुझे नहीं लगता कि यह एक पंक्ति के साथ काम करेगा? .FindAndcount के साथ उदाहरण के लिए, आपको परिणाम पंक्तियों को पूरा करना होगा और जो भी आपकी आवश्यकता है उसे प्राप्त करने के लिए प्रत्येक पर वापस जाएं।
बैकडेस्क

संभवतः JSON.stringify या res.json को चलाना आसान है (यदि आप एक्सप्रेस के भीतर काम कर रहे हैं)।
बैकडेस्क

@backdesk - ने इसे किसी सरणी पर आज़माया नहीं है - लेकिन डॉक्स से ऐसा लग रहा है कि इसे उसी चीज़ को वापस करना चाहिए।
चार्ल्स

3
उपयोग में .get()शामिल संघों को परिवर्तित नहीं किया जाएगा, .get({ plain: true })इसके बजाय उपयोग करें । डॉक्स से सुझाव का उल्लेख करने के लिए धन्यवाद।
वम्स

यदि आप पहले ही क्वेरी निष्पादित कर चुके हैं और तब भी उपयोगी नहीं हैraw: true
मैट मोलनार

49

सबसे अच्छा और सरल तरीका है:

बस Sequelize से डिफ़ॉल्ट तरीके का उपयोग करें

db.Sensors.findAll({
    where: {
        nodeid: node.nodeid
    },
    raw : true // <----------- Magic is here
}).success(function (sensors) {
        console.log(sensors);
});

नोट: [options.raw]: कच्चा परिणाम लौटाएं। अधिक जानकारी के लिए अगली कड़ी देखें।


नेस्टेड परिणाम के लिए / यदि हमारे पास मॉडल शामिल है, तो sequlize के नवीनतम संस्करण में,

db.Sensors.findAll({
    where: {
        nodeid: node.nodeid
    },
    include : [
        { model : someModel }
    ]
    raw : true , // <----------- Magic is here
    nest : true // <----------- Magic is here
}).success(function (sensors) {
        console.log(sensors);
});

यह उत्तर बहुत उपयोगी है, अपने मामले में, जब मैं सॉकेट में एक से अधिक पंक्ति भेजता हूं, तो सीक्वेलाइज़ द्वारा प्रदान की गई देशी कार्यक्षमता का उपयोग करें, स्टैक ओवरऑल त्रुटि हुई।
आशीष कदम

2
यदि आपके पास बाल डेटा की एक सरणी है, तो आपको गलत परिणाम मिलेंगे। इसलिए, यदि पोस्ट की गई क्वेरी sensorsबच्चे के सरणी के साथ केवल एक रिटर्न देती है someModel, तो आपको प्रत्येक में एक arrayके sensorsसाथ एक मिलेगा someModel
रहमत अली

31

उसके जवाब में CharlesA नोटों के रूप में, .values()है तकनीकी रूप से बहिष्कृत कर दिया गया है, हालांकि इस बात को स्पष्ट रूप में बताया गया है नहीं है डॉक्स । यदि आप { raw: true }क्वेरी में उपयोग नहीं करना चाहते हैं , तो पसंदीदा दृष्टिकोण .get()परिणामों पर कॉल करना है।

.get(), हालांकि, एक सरणी का एक तरीका है, एक सरणी का नहीं। जैसा कि ऊपर लिंक किए गए मुद्दे में उल्लेख किया गया है, Sequelize उदाहरण ऑब्जेक्ट्स के मूल सरणियों देता है (और अनुरक्षक उस को बदलने की योजना नहीं बनाते हैं), इसलिए आपको सरणी के माध्यम से खुद को पुनरावृत्त करना होगा:

db.Sensors.findAll({
    where: {
        nodeid: node.nodeid
    }
}).success((sensors) => {
    const nodeData = sensors.map((node) => node.get({ plain: true }));
});

यह मेरे लिए काम किया! हालांकि मुझे नहीं पता कि 'प्राप्त' एक जावास्क्रिप्ट या एक अनुक्रमिक कार्य है। कृपया मुझे ज्ञान दो। धन्यवाद
एंटी

1
@antew यह डेटाबेस से लौटी किसी वस्तु पर एक विधि है - यह सीक्वेल लाइब्रेरी का हिस्सा है, न कि एक देशी जावास्क्रिप्ट फ़ंक्शन।
शेन ह्यूजेस

मुझे इस काम में लाने के लिए उम्र लग गई! धन्यवाद। बहुत मुश्किल था क्योंकि मेरे पास बहुत सारे नेस्टेड शामिल हैं, जो एक बग भी है। इसलिए मुझे कई प्रश्न करने होंगे, और मैं इस वजह से नहीं कर सका !!!
कार्ल टेलर

17

आप मानचित्र समारोह का उपयोग कर सकते हैं। यह मेरे लिए काम किया है।

db.Sensors
    .findAll({
        where: { nodeid: node.nodeid }
     })
    .map(el => el.get({ plain: true }))
    .then((rows)=>{
        response.json( rows )
     });

धन्यवाद यह मेरे उपयोग के लिए सबसे अच्छा समाधान था, बसresults = results.map(el => el.get({ plain: true }))
जोशुआ ओहाना

9

मुझे एक समाधान मिला है जो नेटेड नेटिव फ़ंक्शन का उपयोग करके नेस्टेड मॉडल और सरणी के लिए ठीक काम करता है।

var results = [{},{},...]; //your result data returned from sequelize query
var jsonString = JSON.stringify(results); //convert to string to remove the sequelize specific meta data

var obj = JSON.parse(jsonString); //to make plain json
// do whatever you want to do with obj as plain json

1
इतना सरल, फिर भी शक्तिशाली रूप से काम करता है और मॉडल तर्क रखता है। मुझे नहीं पता कि यह कितना कुशल है, लेकिन यह मेरे लिए काफी अच्छा था। आप इसे कुछ इस तरह से छोटा कर सकते हैं: res = JSON.parse (JSON.stringify (परिणाम));
Artipixel

9

यहां मैं वही प्रयोग कर रहा हूं जो गैर-कड़े मूल्यों और सभी नेस्टेड एसोसिएशनों के साथ sequelizev4 क्वेरी से सादा प्रतिक्रिया ऑब्जेक्ट प्राप्त करने के लिए उपयोग कर रहा है ।

सादे जावास्क्रिप्ट के साथ (ES2015 +):

const toPlain = response => {
  const flattenDataValues = ({ dataValues }) => {
    const flattenedObject = {};

    Object.keys(dataValues).forEach(key => {
      const dataValue = dataValues[key];

      if (
        Array.isArray(dataValue) &&
        dataValue[0] &&
        dataValue[0].dataValues &&
        typeof dataValue[0].dataValues === 'object'
      ) {
        flattenedObject[key] = dataValues[key].map(flattenDataValues);
      } else if (dataValue && dataValue.dataValues && typeof dataValue.dataValues === 'object') {
        flattenedObject[key] = flattenDataValues(dataValues[key]);
      } else {
        flattenedObject[key] = dataValues[key];
      }
    });

    return flattenedObject;
  };

  return Array.isArray(response) ? response.map(flattenDataValues) : flattenDataValues(response);
};

लॉश के साथ (थोड़ा और अधिक संक्षिप्त):

const toPlain = response => {
  const flattenDataValues = ({ dataValues }) =>
    _.mapValues(dataValues, value => (
      _.isArray(value) && _.isObject(value[0]) && _.isObject(value[0].dataValues)
        ? _.map(value, flattenDataValues)
        : _.isObject(value) && _.isObject(value.dataValues)
          ? flattenDataValues(value)
          : value
    ));

  return _.isArray(response) ? _.map(response, flattenDataValues) : flattenDataValues(response);
};

उपयोग :

const res = await User.findAll({
  include: [{
    model: Company,
    as: 'companies',
    include: [{
      model: Member,
      as: 'member',
    }],
  }],
});

const plain = toPlain(res);

// 'plain' now contains simple db object without any getters/setters with following structure:
// [{
//   id: 123,
//   name: 'John',
//   companies: [{
//     id: 234,
//     name: 'Google',
//     members: [{
//       id: 345,
//       name: 'Paul',
//     }]
//   }]
// }]

1
धन्यवाद! ThePlain उम्मीद के मुताबिक काम करता है और साथ ही मेरे मुद्दे को हल करता है।
एरणम

यह साफ-सुथरा है, लेकिन यह अच्छा नहीं है यदि आप अपने मॉडल के किसी भी तरीके को ओवरराइड करते हैं। मैं इसे काफी हद तक या तो बनाया या परिवर्तित करने के लिए अद्यतन / अद्यतन मूल्यों। अब तक केवल एक चीज जो मेरे लिए ठीक से काम कर रही है वह है JSON.parse (JSON.stringify (प्रतिक्रिया))।
हम्मीर

2

नेस्टेड JSON सादे पाठ के लिए

db.model.findAll({
  raw : true ,
  nest : true
})

1
यह एक से कई संघों के लिए अपने उपयोग के लिए बेहतर संघ के लिए उचित काम नहीं करता है। (obj => obj.get ({plain: true}))
मानव कोठारी

वास्तव में मैं db.model.findOne और एक से कई एसोसिएशन के बारे में बात कर रहा हूं।
मानव कोठारी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.