সিক্যুয়ালাইজ করুন, সত্তাকে প্লেইন অবজেক্টে রূপান্তর করুন


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 ব্যবহার করি

আপডেট। কনসোল.লগ (নোড):

{ 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একটি aতিহ্যগত জিনিস হতে হবে না। সম্ভবত এটি একটি বাফার? console.log(node);আপনার কৌতুক রেখার আগে কি বলে?
কেভিন রিলি

পোস্ট আপডেট দেখুন।
রুসলান

উত্তর:


43

যদি আমি আপনাকে সঠিকভাবে পাই তবে আপনি 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পাশাপাশি কাজ করতে পারে।


4
Node.values :): আপনাকে ধন্যবাদ, আমার সব
রুসলান

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));
সোচি হায়াশি

4
এটি গৃহীত উত্তরের চেয়ে সহজ এবং ভাল পন্থা। ধন্যবাদ
পাইপিস্ম

4
@ সোচিহায়শি আসলে, আপনি যখন এটির বিষয়ে চিন্তা করবেন তখন এটির বিপরীত ...;) কাঁচা ব্যতীত: সত্য, সিক্যুইলাইজ কোনওভাবে ফলাফলকে বস্তুতে পূর্ণ করতে পারবেন না। বর্গ কোয়েরি থেকে প্রাপ্ত ফলাফলগুলি ইতিমধ্যে সমতল হয়ে গেছে। আমি এই উত্তরের জন্য একটি সমতল ফলাফল ... +1 পেতে কয়েকবার দরকারী বলে মনে করেছি।
PRS

4
কাঁচা তবে নেস্টেড রেজাল্ট পেতে সোচিহিয়াশী @ আপনি nest: trueপাশাপাশি ব্যবহার করতে পারেন raw: true
ওয়াল্ডিস

কীভাবে raw:trueকোনও বিশ্বব্যাপী সেটিংটি পাস করবেন এমন কোনও ধারণা , তাই এটি প্রতিটি ক্যোয়ারীতে পাস করার দরকার নেই? ধন্যবাদ
কোডবট

109

যারা সম্প্রতি এই প্রশ্নটি নিয়ে আসছেন তাদের .valuesজন্য সিক্যুইলাইজ 3.0.০.০ হিসাবে অবচিত করা হয়েছে। এর .get()পরিবর্তে সরল জাভাস্ক্রিপ্ট অবজেক্টটি ব্যবহার করুন। সুতরাং উপরের কোডটি এতে পরিবর্তিত হবে:

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

Sequelize ডক্স এখানে


6
আমি ভুল হলে আমাকে সংশোধন করুন - তবে আমি মনে করি না এটি সারিগুলির একটি অ্যারে নিয়ে কাজ করবে? উদাহরণস্বরূপ .ফাইন্ডএন্ডকাউন্টের সাথে আপনাকে ফলাফল সারিগুলি ম্যাপ করতে হবে এবং আপনার যা প্রয়োজন তা পেতে প্রতিটিটিতে ফিরে যান get
ব্যাকডেস্ক

সম্ভবত JSON.stringify বা res.json চালানো সহজ (আপনি যদি এক্সপ্রেসের মধ্যে কাজ করছেন)।
ব্যাকডেস্ক

@ ব্যাকডেস্ক - এটি অ্যারেতে চেষ্টা করেননি - তবে দস্তাবেজগুলি থেকে দেখে মনে হচ্ছে এটি একই জিনিসটি ফিরে আসবে।
চার্লসএ

4
ব্যবহার .get()অন্তর্ভুক্ত সংঘগুলি রূপান্তর করবে না, .get({ plain: true })পরিবর্তে ব্যবহার করুন। ডক্স থেকে পরামর্শটি উল্লেখ করার জন্য ধন্যবাদ।
Wumms

এছাড়াও আপনি যদি ইতিমধ্যে ক্যোয়ারী সঞ্চালিত যদি এবং এইভাবে ইস্যু করতে পারবে নাraw: true
ম্যাট Molnar

49

সর্বোত্তম এবং করার সহজ উপায় হ'ল:

সিকুয়েলাইজ থেকে কেবলমাত্র ডিফল্ট উপায়টি ব্যবহার করুন

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

দ্রষ্টব্য: [વિકલ્પો.raw]: কাঁচা ফলাফল ফেরত দিন। আরও তথ্যের জন্য সিক্যুইলাইজ.কোয়ারি দেখুন।


নেস্টেড ফলাফলের জন্য / যদি আমরা সেকুলাইজ এর সর্বশেষ সংস্করণে মডেল অন্তর্ভুক্ত করেছি,

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);
});

এই উত্তরটি খুব কার্যকর, সিক্যুয়ালাইজের দ্বারা সরবরাহিত নেটিভ কার্যকারিতা ব্যবহার করুন, আমার ক্ষেত্রে যখন আমি সকেটে একাধিক সারির প্রেরণ করি তখন স্ট্যাক ওভারফ্লো ত্রুটি ঘটেছিল।
আশীষ কদম

4
আপনার কাছে চাইল্ড ডেটার একটি অ্যারে থাকলে আপনি ভুল ফলাফল পাবেন। সুতরাং, যদি ক্যোয়ারী আয় পোস্ট কেবল এক sensorsশিশু একটি অ্যারের সাথে someModel, আপনি একটি পাবেন arrayএর sensorsএক সঙ্গে someModelপ্রতিটি।
রহমত আলী

31

তার উত্তরে CharlesA নোট হিসাবে, .values()হয় টেকনিক্যালি অবচিত , যদিও এই সত্য স্পষ্টভাবে উল্লেখ করা হয় না ডক্স । আপনি যদি { raw: true }ক্যোয়ারিতে ব্যবহার করতে না চান তবে পছন্দের পদ্ধতির .get()ফলাফলগুলি কল করা।

.get()তবে, উদাহরণস্বরূপের একটি পদ্ধতি, অ্যারের নয় of উপরের লিঙ্কযুক্ত ইস্যুতে উল্লিখিত হিসাবে, সিক্যুলাইজ উদাহরণস্বরূপ বস্তুর নেটিভ অ্যারেগুলি ফেরত দেয় (এবং রক্ষণাবেক্ষণকারীরা এটি পরিবর্তন করার পরিকল্পনা করেন না), সুতরাং আপনাকে নিজেই অ্যারের মাধ্যমে পুনরাবৃত্তি করতে হবে:

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

এটি আমার পক্ষে কাজ করেছিল! যদিও আমি জানি না যে 'get' একটি জাভাস্ক্রিপ্ট বা সিক্যুয়ালাইজ ফাংশন কিনা। আমাকে আলোকিত করুন। ধন্যবাদ
6'18

4
@ এন্টিউ এটি ডাটাবেস থেকে ফিরে আসা কোনও জিনিসের একটি পদ্ধতি - এটি সিক্যুয়ালাইজ লাইব্রেরির অংশ, কোনও নেটিভ জাভাস্ক্রিপ্ট ফাংশন নয়।
শেন হিউজেস

এই কাজের জন্য আমাকে যুগ যুগ ধরে! ধন্যবাদ. এতটা কঠিন ছিল কারণ আমার অনেকগুলি নেস্টেড রয়েছে যা একটি বাগও। সুতরাং আমাকে একাধিক ক্যোয়ারী করতে হবে, এবং এর কারণে আমি পারলাম না !!!
কার্ল টেলর

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

4
এত সহজ, তবু শক্তিশালী কাজ করে এবং মডেলটির যুক্তি রাখে। আমি জানি না এটি কতটা দক্ষ, তবে এটি আমার পক্ষে যথেষ্ট ভাল ছিল। আপনি এটির মতো কিছুতে সংক্ষিপ্ত করতে পারেন: যাক res = JSON.parse (JSON.stringify (ফলাফল));
আর্টপিক্সেল

9

আমি অ-স্ট্রিংফাইড মানগুলি এবং sequelizeভি 4 ক্যোয়ারী থেকে সমস্ত নেস্টেড সংযুক্তিগুলির সাথে সরল প্রতিক্রিয়া অবজেক্টটি পেতে যা ব্যবহার করছি তা এখানে ।

সঙ্গে প্লেইন জাভাস্ক্রিপ্ট (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);
};

সঙ্গে lodash (একটু বেশি সংক্ষিপ্ত):

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',
//     }]
//   }]
// }]

4
ধন্যবাদ! টপ্লেইন প্রত্যাশার মতো কাজ করে এবং আমার সমস্যাটিও সমাধান করে।
এরহনম

এটি ঝরঝরে, তবে আপনি যদি আপনার মডেলের কোনও জেএসওএন পদ্ধতিতে ওভাররাইড করেন তবে এটি ভাল নয়। আমি তৈরি করা এ্যাট / আপডেটেড মানগুলি মুছে ফেলতে বা রূপান্তর করতে এটি বেশ কিছু করি। এখনও পর্যন্ত আমার পক্ষে সঠিকভাবে কাজ করা একমাত্র জিনিস হ'ল JSON.parse (JSON.stringify (প্রতিক্রিয়া))।
হামহাম

2

নেস্টেড জেএসওএন সরল পাঠ্যের জন্য

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

4
এটা অনেক সমিতি এক না কাজ propery করে তার ভালো (obj => obj.get ({প্লেইন: সত্য})) .map ব্যবহার করতে
Manav কোঠারি

আসলে আমি db.model.findOne এবং এক থেকে অনেক সংস্থার কথা বলছি।
মানব কোঠারি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.