Saya tidak terlalu familiar dengan javascript, dan menakjubkan, karena saya tidak bisa menambahkan properti baru, ke objek, yang diambil dari database menggunakan nama ORM Sequelize.js.
Untuk menghindari ini, saya menggunakan peretasan ini:
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);
});
Jadi, cara apa biasanya untuk menambahkan properti baru ke objek.
Jika bisa membantu, saya menggunakan sequelize-postgres versi 2.0.x.
upd. console.log (node):
{ 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] } } }
Saya pikir selanjutnya, apa yang Anda pikirkan: "Oke, itu mudah, tambahkan saja properti Anda ke dataValues."
node.selectedValues.sensors = sensors;
node.dataValues.sensors = sensors;
Saya menambahkan baris ini, dan ini tidak berhasil
node.js
sequelize.js
Ruslan
sumber
sumber
node
tidak boleh menjadi objek tradisional. Mungkin itu Buffer? Apa yang dikatakanconsole.log(node);
sebelum garis trik Anda?Jawaban:
Jika saya mengerti, Anda ingin menambahkan
sensors
koleksi kenode
. Jika Anda memiliki pemetaan di antara kedua model, Anda dapat menggunakaninclude
fungsionalitas yang dijelaskan di sini atauvalues
pengambil yang ditentukan di setiap instance. Anda dapat menemukan dokumennya di sini .Yang terakhir dapat digunakan seperti ini:
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); });
Ada kemungkinan yang
nodedata.sensors = sensors
bisa berhasil juga.sumber
Anda bisa menggunakan opsi kueri
{raw: true}
untuk mengembalikan hasil mentah. Kueri Anda harus seperti berikut:db.Sensors.findAll({ where: { nodeid: node.nodeid }, raw: true, })
juga jika Anda memiliki asosiasi dengan
include
yang diratakan. Jadi, kita bisa menggunakan parameter lainnest:true
db.Sensors.findAll({ where: { nodeid: node.nodeid }, raw: true, nest: true, })
sumber
nest: true
bersamaraw: true
.raw:true
sebagai pengaturan global, jadi tidak perlu meneruskannya ke setiap kueri? Terima kasihBagi mereka yang menemukan pertanyaan ini baru-baru ini,
.values
tidak berlaku lagi pada Sequelize 3.0.0. Gunakan.get()
sebagai gantinya untuk mendapatkan objek javascript biasa. Jadi kode di atas akan berubah menjadi:var nodedata = node.get({ plain: true });
Sequelize dokumen di sini
sumber
.get()
tidak akan mengonversi asosiasi yang disertakan, gunakan.get({ plain: true })
sebagai gantinya. Terima kasih telah menyebutkan saran dari dokumen.raw: true
Cara terbaik dan sederhana untuk melakukannya adalah:
Cukup gunakan cara default dari Sequelize
db.Sensors.findAll({ where: { nodeid: node.nodeid }, raw : true // <----------- Magic is here }).success(function (sensors) { console.log(sensors); });
Untuk hasil bersarang / jika kita sudah memasukkan model, Dalam versi terbaru dari 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); });
sumber
sensors
dengan array anaksomeModel
, Anda akan mendapatkanarray
darisensors
dengan satusomeModel
di masing-masing.Seperti yang dicatat CharlesA dalam jawabannya,
.values()
secara teknis tidak digunakan lagi , meskipun fakta ini tidak secara eksplisit disebutkan dalam dokumen . Jika Anda tidak ingin menggunakan{ raw: true }
dalam kueri, pendekatan yang disukai adalah memanggil.get()
hasil..get()
, bagaimanapun, adalah metode sebuah instance, bukan dari sebuah array. Seperti disebutkan dalam masalah terkait di atas, Sequelize mengembalikan array asli objek instance (dan pengelola tidak berencana mengubahnya), jadi Anda harus mengulang sendiri melalui array:db.Sensors.findAll({ where: { nodeid: node.nodeid } }).success((sensors) => { const nodeData = sensors.map((node) => node.get({ plain: true })); });
sumber
Anda dapat menggunakan fungsi peta. ini berhasil untuk saya.
db.Sensors .findAll({ where: { nodeid: node.nodeid } }) .map(el => el.get({ plain: true })) .then((rows)=>{ response.json( rows ) });
sumber
results = results.map(el => el.get({ plain: true }))
Saya telah menemukan solusi yang berfungsi dengan baik untuk model dan array bersarang menggunakan fungsi JavaScript asli.
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
sumber
Inilah yang saya gunakan untuk mendapatkan objek respons biasa dengan nilai non-string dan semua asosiasi bersarang dari
sequelize
kueri v4.Dengan JavaScript biasa (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); };
Dengan lodash (sedikit lebih ringkas):
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); };
Penggunaan :
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', // }] // }] // }]
sumber
Untuk teks biasa JSON bertingkat
db.model.findAll({ raw : true , nest : true })
sumber