Update multiple rows in sequelize with different conditions - javascript

I'm trying to perform an update command with sequelize on rows in a postgres database. I need to be able to update multiple rows that have different conditions with the same value.
For example, assume I have a user table that contains the following fields:
ID
First Name
Last Name
Gender
Location
createdAt
Assume, I have 4 records in this table, I want to update records with ID - 1 and 4 with a new location say Nigeria.
Something like this: SET field1 = 'foo' WHERE id = 1, SET field1 = 'bar' WHERE id = 2
How can I achieve that with sequelize?

You can update multiple record at a time , but same updates for all records
, if you want to make different updates for different conditons then you have to run that multiple time
Example :
This will update fields1 to foo , where id is 1 or 4
let ids = [1,4];
Your_model.update({ field1 : 'foo' },{ where : { id : ids }});
This will update field1 to foo if id is 1 , and field1 to bar if id is 4
Your_model.update({ field1 : 'foo' },{ where : { id : 1 }});
Your_model.update({ field1 : 'bar' },{ where : { id : 4 }});
Hope this will clear all your doubts.

You can update multiple rows following your conditions, and to do that the operators are very helpful.
Look here: http://docs.sequelizejs.com/manual/querying.html (operators)
const { Op } = Sequelize;
DisplayMedia.update(
{
field: 'bar'
},
{
where: {
id: {
[Op.in]: [1, 10, 15, ..] // this will update all the records
} // with an id from the list
}
}
)
There is all kinds of operators, including the range operators, or like operator ...etc
Also one of the important questions when it come to update, is how to update all rows?
Not including where results in an error "Missing where attribute in the options parameter passed to update".
The answer is in the code bellow: provide a where with an empty object.
await DisplayMediaSequence.update({
default: false
}, {
where: {}, // <-- here
transaction
});
await DisplayMediaSequence.update({
default: true <-- after all turned to false, we now set the new default. (that to show a practical expample) -->
}, {
where: {
id
},
transaction
});

we planning to save different values for same fields in multiple row there is a possible for getting all field values are same in database.
using for loop
const {idArray,group_id} = params;
for(const item of idArray){
const response = await Your_model.findOne({ where:{group_id,user_id:null}, order: [['id', 'DESC']] });
await response.update({user_id:item});
}

Related

How to read in this MongoDb field that contains dynamic children fields, in JavaScript?

Given the following MongoDB document structure (which I cannot change), I'm not sure how to read this in JavaScript?
so loginHistory is the main field name. It contains an Object type (okay???)
it can then contain multiple children fields (this above example has only ONE child), which are arrays. These field names are dynamic, but unique.
the 'array' content is a C# DateTimeOffset , I've been told.
So in the example above, Jane is the field and the value is an Array, but really it's a DateTime.Offset.
Here's another document I've found:
4x fields
So i don't know how to read this with node/JavaScript. Oh - and the field loginHistory might not exist on some documents, also :(
So given that existing document schema/structure, I need to somehow read in each loginHistory value and then create a new document (which i'll do other stuff with later).
This is some JavaScript code I tried, but doesn't work:
users.loginHistory.forEach(loginHistory => {
// do stuff, like create a new { id = users._id, name = "Jane", createdOn = "that date/time offset" }
}
Assuming we have an input set of docs like the screen shots e.g.:
var r = [
{
loginHistory: {
"Jane": [ 1648835363929, 0 ],
"Bob": [ 1648835363929, 0 ]
}
},
{
noLoginHistory: "nope"
},
{
loginHistory: {
"Dan": [ 1648835363929, 0 ],
"Dave": [ 1648835363929, 0 ],
"Jane": [ 1648835363929, 0 ]
}
}
];
then the following pipeline will create new, "converted" docs in a collection named foo2.
db.foo.aggregate([
// OK if loginHistory does not exist. X will be set to null
// and the $unwind will not produce anything:
{$project: {X: {$objectToArray: "$$ROOT.loginHistory"} }},
{$unwind: "$X"},
// Now we have individual docs of
// X: {k: name, v: the array}
// The OP wanted to make a new doc for each one. I don't know
// what function to apply to turn X.v[0] into a MongoDB datetime
// because I don't know what that big int (637807576034080256) is
// supposed to be so I used regular ms since epoch for the example
// instead. The OP will have to get more creative with division
// and such to turn 637807576034080256 into something "toDate-able"
// in MongoDB. You *could* store the big int as is but it is always
// good to try to turn a datetime into a real datetime in mongodb.
{$project: {
_id: false,
name: '$X.k',
createdOn: {$toDate: {$arrayElemAt:['$X.v',0]}}
}}
// Now we have docs like :
// {name: "Jane", createdOn: ISODate(...) }
// By calling $out to a new collection, a new _id will be assigned
// to each:
,{$out: "foo2"}
]);

mongoDB - Regex search against partial field values

I've a collection of countries with country calling code in the country object. How can I find a country using calling code with a mobile number?
const countries = [
{
name: 'UAE',
callingCode: 971
},
{
name: 'USA',
callingCode: 1
},
{
name: 'UK',
callingCode: 44
}
];
const number = '971524500000'; // Input
How can I find country for the given mobile using regex in mongoose javascript;
[https://en.wikipedia.org/wiki/List_of_country_calling_codes][1]
Take a look at the link above on country calling codes, and specifically see the section "Tree List".
One solution would be to implement a schema in Mongo based on this tree in order to decode the country codes.
So, a table could be created to store Mongo documents containing a field "1x" "2x" "21x" etc (the Y axis in the Tree List table).
Each of these documents could contain an array of sub-documents from x=0 to x=9 (the x axis in the Tree List table). The sub-document can contain the country name/code you are looking for. You can use a direct index into the array in the Mongo document for an efficient lookup.
I think you'll find this to be a pretty efficient implementation and should cover all the bases.
If you can restructure your array to an object this would be the fastest
const countries =
{
971: 'UAE',
1: 'USA',
44: 'UK',
}
;
var code = 44;
console.log(countries[code]);
const countries = [
{
name: 'UAE',
callingCode: 971
},
{
name: 'USA',
callingCode: 1
},
{
name: 'UK',
callingCode: 44
}
];
var myFound =countries.filter(myFunc.bind(this,44));
function myFunc(code,element) {
if(element.callingCode == code){
return element;
}
}
console.log(myFound);
On MongoDB v 4.2 - you can use $let & $regexFind to do this :
db.collection.aggregate([
{
$match: {
$expr: {
$eq: [
{
$let: {
vars: {
value: {
$regexFind: {
input: "971524500000", // pass in as string
regex: { $toString: "$callingCode" }
}
}
},
in: "$$value.idx",
}
},
0
]
}
}
}
]);
Test : MongoDB-Playground
Explanation :
General Use-case :
In general regex searches - Will have an input which will be sub-string of actual string, Ex.:-
Actual string in DB : 'We can do it in mongo'
Input : mongo (/mongo/ - will work)
Your Use-case :
From above case as mongo exists in actual string/value of db field then you can get that document, But your case is different :
Actual string in DB : mongo
Input : 'We can do it in mongo'
This doesn't work that way, So using normal /We can do it in mongo/ isn't going help you here (Also doing few tricks with regex). So we need to make a trick to $regexFind operator. Unlike mongo documentation we need take 971524500000 into input field & regex as string value of callingCode field which is vice-versa to what's given in documentation.
So once we do that, We would get something like below :
{
"match" : "971", /** value of callingCode field */
"idx" : 0, /** Index of `971` in '971524500000' */
"captures" : []
},{
"match" : "1",
"idx" : 2,
"captures" : []
},
null /** 3rd doc no match */
As country code has to be at first of given number we need docs where "idx" : 0 - So we're using $let to get index of returned object & checking against 0 & eventually getting respective docs using $match.
Note :
There is something you need to look into, Just in case if you've docs like below :
{
"_id": ObjectId("5e8f67091aa1cc3d2158ade1"),
"name": "USA",
"callingCode": 1.0
},
{
"_id": ObjectId("5e8f67091aa1cc3d2158ade3"),
"name": "somecountry",
"callingCode": 197.0
}
& input is 1971524500000, then this query will bring both docs in result. This will be the case you need to check on. Anyhow I would suggest to try this query, rather than getting all documents for collection to the code & extract required o/p this might be better to do.

Sequelize wrap column with " in where condition

I have a JSONB column in DB.
I'd like to have request to DB where I can check if some value in this JSON it true or false:
SELECT *
FROM table
WHERE ("json_column"->'data'->>'data2')::boolean = true AND id = '00000000-1111-2222-3333-456789abcdef'
LIMIT 1
So, my sequelize request:
const someVariableWithColumnName = 'data2';
Model.findOne({
where: {
[`$("json_column"->'data'->>'${someVariableWithColumnName}')::boolean$`]: true,
id: someIdVariable,
},
order: [/* some order, doesn't matter */],
})
And sequelize generate bad result like:
SELECT *
FROM table
WHERE "(json_column"."->'data'->>'data2')::boolean" = true AND id = '00000000-1111-2222-3333-456789abcdef'
LIMIT 1
Split my column by . and add " to every element.
Any idea how to get rid of adding " to the column in where condition?
Edit:
Here is my query with sequelize.literal():
const someVariableWithColumnName = 'data2';
Model.findOne({
where: {
[sequelize.literal(`$("json_column"->'data'->>'${someVariableWithColumnName}')::boolean$`)]: true,
id: someIdVariable,
},
order: [/* some order, doesn't matter */],
})
You can use Sequelize.literal() to avoid spurious quotes. IMHO, wrapping the json handling in a db function might also be helpful.
I just came across a similar use case.
I believe you can use the static sequelize.where method in combination with sequelize.literal.
Here is the corresponding documentation in sequelize API reference: https://sequelize.org/master/class/lib/sequelize.js~Sequelize.html#static-method-where
And here is an example (although I will admit hard to find) in the regular documentation:
https://sequelize.org/master/manual/model-querying-basics.html#advanced-queries-with-functions--not-just-columns-
In the end for your specific sit try something like this:
const someVariableWithColumnName = 'data2';
Model.findOne({
where: {
[Op.and]: [
// We provide the virtual column sql as the first argument of sequelize.where with sequelize.literal.
// We provide the matching condition as the second argument of sequelize.where, with the usual sequelize syntax.
sequelize.where(sequelize.literal(`$("json_column"->'data'->>'${someVariableWithColumnName}')::boolean$`), { [Op.eq]: true }),
{ id: someIdVariable }
]
})

Create a select option in the react js from an object

I am new to the react-redux. I actually know this question is a very basic question,
Here, I have an object which is like,
questionsCount : [ {
Id : "CSS"
count: "1",
level:"Easy",
type: Non_code},{
Id : "CSS"
count: "2",
level:"Medium",
type: code},
{
Id : "CSS"
count: "5",
level:"Tough",
type: code},
{
Id : "java"
count: "2",
level:"Tough",
type: Non-code},
{
Id : "Html"
count: "4",
level:"Easy",
type: code},]
Now,I have one select drop-down where I want to create an options , So I tried
return this.state.questionsCount.map((item) =>
<option key={item.Id}>{item.Id}</option>
);
In the props I get the level type.
Now, Here what its creating all the option elements with repetative Id's.
Now, What I want to do is that,
the option element will be like, first it should have only provided level elements meanes,
css code:0,Non_code:1
So,Currently Its getting duplicated .
Its getting duplicated because Id is getting repeated. Can any one help me with this ? Thanks
Here,I have that object. Now In that object there are multiple objects which has Id and count and level and type .
Now, from this objects I want to create the select options from this.
It has three diff levels.
expected Output would be like ,
It will be having only easy level
<option>Css code:0,non_code-1></option>
<option>Html code:4,non_code-0></option>
for tough options,
<option>Css code:5,non_code-1></option>
<option>java code:0,non_code-2></option>
same for medium.and tough.
One technology can have code type or non code type questions of type easy or medium or tough. So, I want to create the drop-down of that technolgy depends upon the levels.
If code or non-code not present then it will have 0 for that.
From what I understand in your case, you wish to create a select dropdown based on the difficulty level. To achieve that, you would need to filter our the question based on difficult first before rendering like
processQuestions(questionsCount, difficulty) {
const res = questionsCount.filter(item => item.level === difficulty);
return res.reduce((acc, item) => {
if (acc[item.Id]) {
acc[item.Id] = { ...acc[item.Id], [item.type]: acc[item.Id][item.type]? acc[item.Id][item.type] + 1 : 1};
} else {
acc[item.Id] = { [item.type]: 1};
}
return acc;
}, {})
}
render() {
const { difficulty } = this.props;
const questionsData = this.processQuestions(this.state.questionCount, difficulty);
return Object.entries(questionsData).map(([questionId, data]) => {
return (
<option key={questionId}>{questionId} code: {data.code} non_code: {data['Non-code']}</option>
)
})
}

How do I access the additional columns in models that inherit from a parent-type when querying Bookshelf.js

In my project, I have a parent table 'Tasks' with fields like 'owner_id' and 'title'. I also have two specific variations of Tasks called 'TaskFind' and 'TaskFix'. These both extend the 'Tasks' table and offer additional columns.
I have no problem creating instance of the children models using Bookshelf's forge. But when I try and query for all Tasks, I don't have access to the fields in the extended models.
For example, pretend I have a database with one instance of TaskFix and one instance of TaskFind. If I query for all Tasks like this:
Task
.fetchAll()
.then(results => {
res.json(results);
});
the results look something like this
{
{
id : 1,
owner_id : 1,
title : "My TaskFind"
},
{
id : 2,
owner_id : 1,
title : "My TaskFix"
}
}
when really, I want them to look like this:
{
{
id : 1,
owner_id : 1,
title : "My TaskFind"
additional_columns : ...
},
{
id : 2,
owner_id : 1,
title : "My TaskFix"
additional_columns : ...
}
}
If I query them individually, I get the extra columns. For example:
TaskFix // (rather than just 'Task')
.fetchAll()
.then(results => {
res.json(results);
});
works and retrieves all additional columns.
Any idea if this is possible in Bookshelf.js? If not, is there a good workaround?

Categories