How to Update JSON data in an array - arrays

I have a JSON Column in my table that has an array of JSON Data like this:
save_data
[
{"option_id": 20000, "question_id": 10000},
{"option_id": 20001, "question_id": 10001},
{"option_id": 20002, "question_id": 10002}
]
I can get the record using this:
$save_data = DB::table('save_state')
->whereJsonContains('save_data', [["option_id" => 20002]])
->get();
But now what I want is to update only the option_id value of the element which has the question_id that I want, for example:
change option_id value to "20003" of question_id = "10002"
I have tried this but it still doesn't work.
$save_data = DB::table('save_state')
->whereJsonContains('save_data', [["option_id" => 20002]])
->update(['save_data->option_id' => [20003]]);

Related

React - Update or Replace an Object with in the State object

I have an State varaible with array of objects like this.
type State = {
Dp: ArrayDataProvider<string, Message>;
};
Inside Dp i will have data which will hold the data in the form of array like this.
[{
"id": 1,
"name": "January",
"abc": abc,
"xyz": xyz
}, {
"id": 2,
"name": "February",
"abc": abc,
"xyz": xyz
}]
I want to replace the object which is having id 2 with the different object and i want to have my object like this .
[{
"id": 1,
"name": "January",
"abc": abc,
"xyz": xyz
}, {
"id": 2,
"name": "New month",
"abc": 1234abc,
"xyz": someVlaue
}]
how to do it in efficient way with typescript in react.
I have done something like this but not working
const data = this.state.Dp?.data.slice();
const index = data.findIndex(currentItem => {
return currentItem.id === updateData[0].id;
});
data[index] = updateData;
this.state.Dp.data = data;
this.setState({ Dp: this.state.Dp });
I use map to do this:
const data = this.state.Dp?.data.map(currentItem => {
return currentItem.id === updatedItem.id ? updatedItem : currentItem;
})
map creates a new array with the items from the previous array, but it gives you an opportunity to make adjustments to the items in the new array as it iterates through them. In my example, I'm checking the id of the item to see if it's the one you want to update, and swapping in your updatedItem if the ids match.
I'm not sure about the TypeScript part, to be honest. I haven't worked with it yet.
Note - I'm not sure what form your updateData is in, so you might have to adjust that. It seems like you want it to be an object, but in one of your lines you're treating it like an array.
Use findIndex to find index of the object where id is equal 2, then replace new object to that place.
let tempArray = [...array];
const index = tempArray.findIndex((element) => element.id === 2);
tempArray[index] = {
id: 2,
name: "New month",
abc: "1234abc",
xyz: "someVlaue"
};
setArray(tempArray);

How to insert a value in an array field inside mongodb collection?

I want to insert a string in an array of strings that is present in a mongodb collection.
the collection looks like:
{
"_id": some id,
"urls": [url1,url2]
}
I want to insert a string on every insert call to the urls array
How can I do it?
The $push operator changed some time back to allow an array of 1 to n items to be inserted into an existing array at an arbitrary position:
db.foo.find();
{ "_id" : 0, "items" : [ "url1", "url2" ] }
// Position starts at 0. Let's use position 1 for the demo:
db.foo.update({_id:0},{$push: {"items": {$each: ["foo","bar"], $position: 1}}});
db.foo.find();
{ "_id" : 0, "items" : [ "url1", "foo", "bar", "url2" ] }
Note that position can also be negative. -1 is the end of the array, -2 is 1 item in from the end, etc. To insert something into the items array in every doc, provide the {} predicate and multi:true option:
db.foo.update({},{$push: {"items": {$each: ["foo","bar"], $position: 1}}},{multi:true});
your post request, with express.js for example, will look something like this:
const urlRouter = express.Router();
urlRouter.route('/your_route_here').post((req, res, next) => {
yourMongoCollectionSchema.create(req.body)
.then(url => {
console.log("Url added", url);
res.setHeader('Content-Type', 'application/json');
res.json(url);
}, err => next(err))
.catch(err => next(err));
})

Need to create collection of keys with multiple values (Laravel 7.x)

My first post here. I tried to search for an answer, but no luck, so here we go
Generally I cannot share with you with the exact code I'm working on :(
so here's the example one:
$collection = collect(['country' => 'Germany', 'city' => 'Berlin', 'month' => 'April']);
dd($collection);
//"country" => "Germany"
//"city" => "Berlin"
//"month" => "April"
$array1 = ['France', 'Paris', 'May'];
$array2 = ['Spain', 'Madrid', 'June'];
My question is - how to "add" those arrays (minding array1 and array2 order) so I end up with something like this?
dd($newCollection);
//output:
//"country" => ["Germany", "France", "Spain"]
//"city" => ["Berlin", "Paris", "Madrid"]
//"month" => ["April", "May", "June"]
OR
If there's a way to get all records from database and make one of the rows a key and a selection of them as values
Example
$users = User::get();
//this table has columns "full_name", "e-mail", "job", "birth_date", "city" and "password"
$collection = <<???>> //make column "full_name" as key and columns "e-mail", "job", "password" as values
dd($collection);
//output:
//"John Doe" => ["johndoe#mail.com", "Janitor", "topsecret"]
//"Jane Doe" => ["janedoe#mail.com", "teacher", "sercretpassword"]
Lifetime gratitude in advance for an answer... I've read Laravel's documentation many times and could not find a solution
I've got this
The solution for me looks like this:
$users = User::get();
//this table has columns "id", "full_name", "e-mail", "job", "birth_date", "city" and "password"
//I don't want to use all columns here
foreach($users as $user=>$value){
$full_name = $value->full_name;
$e-mail = $value->e-mail;
$job = $value->job;
$password -> $value->password;
$endresult[] = [$full_name, $e-mail, $job, $password];
}
$collection = collect($users->keyBy('id')->pluck('id'))->combine($endresult);
dd($collection);
//output:
// 1 => ["John Doe", "johndoe#mail.com", "Janitor", "topsecret"]
// 2 => ["Jane Doe", "janedoe#mail.com", "teacher", "sercretpassword"]
It looks terrible, but works like a charm. I needed to format this like so because in my project there are many foreign keys and I need to pagify my results, so to make it the easiest way possible I need to combine all values to one key (just like a row in csv) rather than call for every value in view
thank you for your support
You've technically asked two questions here. One where you merge a set of values into a key-value collection, and another where you simply limit the values from a set of key-value collections and key by the ID.
Given that you're really looking for an answer to the second question, by way of your answer, here's a cleaner way of doing it:
User::select('id', 'full_name', 'email', 'job', 'password')
->get()
->keyBy('id')
->map(function($user) {
return collect($user)->except('id');
});

Date sorting is not working in muidatatable

https://codesandbox.io/s/stupefied-volhard-jntyu?fontsize=14&hidenavigation=1&theme=dark
this is my codesand box code. on date column result is not showing correctly.
I think the problem with the sort behaviour is that you are trying to sort strings of dates where the year is the last element.
In case you could edit your data directly, try putting the year, the month and so on. Something like:
const data = [
...,
[
"Mason Ray",
"Computer Scientist",
"San Francisco",
39,
142000,
"2019-10-03"
]
Here is an example using date-fnslibrary to parse your input data.
A detail of how is done:
const data = [...].map(info =>
info.map((val, index) => {
const date = new Date(val)
return index === 5
? isValid(date)
? format(date, 'yyyy-MM-dd')
: val
: val
})
)

Is it possible to project fields based on the field name in mongodb?

In a collection, the documents may contains fields like "name", "name:en", "name:de"
{
_id:123456
tag:{
name: HongKong
name-zh: 香港
other_tag1: value1
other_tag2: value2
}
}
{
_id:123457
tag:{
name-en: Beijing
other_tag1: value1
other_tag2: value2
}
}
What I want is to list out all fields with field name contains "name". I tried with the following codes, but it seems to be stupid, and doesn't list all possible "name"s.
find = {'$or': [{'tag.name': {'$exists': 1}}, {'tag.name:zh': {'$exists': 1}}, {'tag.name:en': {'$exists': 1}}]}
project = {'_id': 0, 'name': '$tag.name', 'name:zh': '$tag.name:zh', 'name:en': '$tag.name:en'}
names = list(db.node.aggregate([{'$match': find}, {'$project': project}]))
And the result I want is:
{
name: HongKong
name-zh: 香港
}
{
name-en: Beijing
}
Its possible to search field names using $objectToArray It may not a optimal solution based on data you need to search.
$objectToArray to change the tag into array of key value pair followed by $unwind to search the keys for the input pattern and $group + $arrayToObject to return the matching key value pairs.
db.col.aggregate([
{$match:{'$or': [{'tag.name': {'$exists': 1}}, {'tag.name-zh': {'$exists': 1}}, {'tag.name-en': {'$exists': 1}}]}},
{$project:{"tagskv":{$objectToArray:"$tag"}}},
{$unwind:"$tagskv"},
{$match:{"tagskv.k": { $regex: /name/i }}},
{$group:{_id:"$_id", names:{$push:"$tagskv"}}},
{$project:{"names":{$arrayToObject:"$names"}}},
{$replaceRoot:{newRoot:"$names"}}
])

Resources