Sometimes i only want to select a single value from multiple rows.
Lets imagine i have an account model which looks like this:
Account
And i would only like to select the names.
You would write something like this:
AccountModel.findAll({
where: {
Age: {
$gt : 18
}
},
attributes: ['Name'],
raw : true
});
But this would return in an array with objects.
[{Name : "Sample 1"}, {"Name" : "Sample 2"}]
I would like to get an array with only names like this:
["Sample 1", "Sample 2"]
Is it possible to achieve this with Sequelize? I've searched trough the documentation but couldn't find it.
2020 Solution
Hi folks, you can easily do your pure "pluck" method:
const someVariable = [
... ( await AccountModel.findAll({
where: {
Age: {
$gt : 18
}
},
attributes: ['Name'],
raw : true
})),
].map(account => account.Name);
Using Sequelize 3.13.0 it looks like it isn't possible to have find
return a flat array of values rather than an array of objects.
One solution to your problem is to map the results using underscore or lodash:
AccountModel.findAll({
where: {
Age: {
$gt : 18
}
},
attributes: ['Name'],
raw : true
})
.then(function(accounts) {
return _.map(accounts, function(account) { return account.Name; })
})
I've uploaded a script that demonstrates this here.
As a quick note, setting raw: true
makes the Sequelize find methods return plain old JavaScript objects (i.e. no Instance methods or metadata). This may be important for performance, but does not change the returned values after conversion to JSON. That is because Instance::toJSON always returns a plain JavaScript object (no Instance methods or metadata).
Here is a nice ES6 version of cfogelberg's answer using lambda expressions (Array.prototype.map()
only works in IE9+ and lambda (arrow) functions have no IE support):
AccountModel.findAll({
where: {
Age: {
$gt : 18
}
},
attributes: ['Name'],
raw : true
})
.then(accounts => accounts.map(account => account.Name));
Here is a baby snippet I used for proof of concept. If it doesn't work, you are using one of the unsupported browsers mentioned above (and you shouldn't be making db calls directly from the browser anyway):
let objArray=[{key:1},{key:2},{key:3}];
console.log("Not IE friendly:");
console.log(objArray.map(obj => obj.key));
console.log("IE friendly (might even be ES3 if you change \"let\" to \"var\"):");
let names = [];
for(let i=0 ; i<objArray.length ; i++){
names[i] = objArray[i].key
}
console.log(names)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With