Updating array elements that matches a specific criteria - rethinkdb

Let's say I have the following array
var data = [{ id: 0, points: 1 }, { id: 1, points: 2 }]
I would like to update my table which contains
{
"doc-1": {
"id": "abcxyz123",
"entries": [
{ "id": 0, "points": 5 },
{ "id": 1, "points": 3 },
{ "id": 2, "points": 0 }
]
}
}
so that I add the points-field in the data array to the points-field for each element in the "entries" array in "doc-1" that matches the corresponding id in the data array. The end result would look like:
{
"doc-1": {
"id": "abcxyz123",
"entries": [
{ "id": 0, "points": 6 },
{ "id": 1, "points": 4 },
{ "id": 2, "points": 0 }
]
}
}
How do I go about to write such a query in ReQL?

I assume that the actual document in the table looks like this for now:
{
"id": "abcxyz123",
"entries": [{
"id": 0,
"points": 5
}, {
"id": 1,
"points": 3
}, {
"id": 2,
"points": 0
}]
}
That is without the doc-1 nesting.
Then your update can be done like this:
r.table('t1').update(
{
entries: r.row('entries').map(function(e) {
return r.do(r.expr(data)('id').indexesOf(e('id')), function(dataIndexes) {
return r.branch(
dataIndexes.isEmpty(),
e,
{
id: e('id'),
points: e('points').add(r.expr(data)(dataIndexes(0))('points'))
});
});
})
})
I'm using map to map over each entry in entries, and indexesOf to find the corresponding entry in data if it exists.
Note that this doesn't add new entries to the entries list, but only updates existing ones. Please let me know if you need to add new entries as well.
If your documents actually have the doc-1 field first, this query should do the job:
r.table('t1').update(
{ 'doc-1':
{
entries: r.row('doc-1')('entries').map(function(e) {
return r.do(r.expr(data)('id').indexesOf(e('id')), function(dataIndexes) {
return r.branch(
dataIndexes.isEmpty(),
e,
{
id: e('id'),
points: e('points').add(r.expr(data)(dataIndexes(0))('points'))
});
});
})
}
})

Related

Laravel createMany error on nested relation

This is in relation to this question. I'm having this error:
TypeError
Illuminate\Database\Grammar::parameterize(): Argument #1 ($values) must be of type array, int given, called in /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php on line 920
While inserting data using createMany. This is the form request data:
{
"name": "My Order",
"orders": [
{
"date": "2022-05-17",
"product_id": [1],
"price": 1
},
{
"start_date": "2022-05-18",
"product_id": [2],
"price": 2
}
]
}
This is the store method:
$order = auth()->user()->orders()->create($request->validated());
$order_subs = $order->subOrders()->createMany($request->orders);
$order_sub_items = $request->only('orders')['orders'];
foreach ($order_subs as $key => $value) {
$value->subOrderProducts()->createMany([$order_sub_items[$key]);
}
However, if the product_id is not an array, it will store properly. Sample form request data:
{
"name": "My Order",
"orders": [
{
"date": "2022-05-17",
"product_id": 1,
"price": 1
},
{
"start_date": "2022-05-18",
"product_id": 2,
"price": 2
}
]
}
How to fix this error?

Search by results of previous search in elasticsearch

It is possible to make a search by the results of another search?. For example:
// index: A
{ "ID": 1, "status": "done" }
{ "ID": 2, "status": "processing" }
{ "ID": 3, "status": "done" }
{ "ID": 4, "status": "done" }
// index: B
{ "ID": 1, "user": 1, "value": 10 }
{ "ID": 1, "user": 2, "value": 3 }
{ "ID": 2, "user": 1,"value": 1 }
{ "ID": 3, "user": 1, "value": 3 }
{ "ID": 4, "user": 1, "value": 7 }
Q1: Search in index "A" status == "done" and return the ID
RES: 1,3,4
Q2: From the results in Q1 search value > 5 and return the ID
RES: 1,4
My current solution is use two queries and download the results of "Q1" and make a second search in "Q2" but is very complicated because have 30k of results.
the problem to me seems to be more of a traditional union of filters in 2 indexes sort of a join , what we have in relational databases , not sure of the exact solution but recently had used a plug-in for the joins -> https://siren.io/siren-federate-20-0-introducing-a-scalable-inner-join-for-elasticsearch/ this might help

ReferenceManyFields (One to Many Relationship)

I am working on a project where I have to create one to many relationships which will get all the list of records referenced by id in another table and I have to display all the selected data in the multi-select field (selectArrayInput). Please help me out in this, if you help with an example that would be great.
Thanks in advance.
Example:
district
id name
1 A
2 B
3 C
block
id district_id name
1 1 ABC
2 1 XYZ
3 2 DEF
I am using https://github.com/Steams/ra-data-hasura-graphql hasura-graphql dataprovider for my application.
You're likely looking for "nested object queries" (see: https://hasura.io/docs/1.0/graphql/manual/queries/nested-object-queries.html#nested-object-queries)
An example...
query MyQuery {
district(where: {id: {_eq: 1}}) {
id
name
blocks {
id
name
}
}
}
result:
{
"data": {
"district": [
{
"id": 1,
"name": "A",
"blocks": [
{
"id": 1,
"name": "ABC"
},
{
"id": 2,
"name": "XYZ"
}
]
}
]
}
}
Or...
query MyQuery2 {
block(where: {district: {name: {_eq: "A"}}}) {
id
name
district {
id
name
}
}
}
result:
{
"data": {
"block": [
{
"id": 1,
"name": "ABC",
"district": {
"id": 1,
"name": "A"
}
},
{
"id": 2,
"name": "XYZ",
"district": {
"id": 1,
"name": "A"
}
}
]
}
}
Setting up the tables this way...
blocks:
districts:
Aside: I recommend using plural table names as they are more standard, "districts" and "blocks"

Laravel - Sort array by string value first and then date

I need help to sort array by couple of logics
[
{
"id": 1,
"status": "pending",
"date": "2019-08-01"
},
{
"id": 2,
"status": "delivered",
"date": "2019-08-01"
},
{
"id": 3,
"status": "pending",
"date": "2019-08-03"
},
{
"id": 4,
"status": "delivered",
"date": "2019-08-03"
},
{
"id": 5,
"status": "delivered",
"date": "2019-08-02"
}
]
what I want to do is to sort the array to status pending show first, and then sort it by the date descending
I already test to using sortByDesc from laravel collection but the array looks like sorted it by just 1 function
$collection = $collection->sortByDesc('date')->sortByDesc(function ($row, $key) {
if($row['status'] == 'pending'){
return 1;
}else{
return 0;
}
});
My expected final result look like this :
[
{
"id": 3,
"status": "pending",
"date": "2019-08-03"
},
{
"id": 1,
"status": "pending",
"date": "2019-08-01"
},
{
"id": 4,
"status": "delivered",
"date": "2019-08-03"
},
{
"id": 5,
"status": "delivered",
"date": "2019-08-02"
},
{
"id": 2,
"status": "delivered",
"date": "2019-08-01"
}
]
Few solutions:
Use a custom callback and return an array source
$products->sortBy(function($product) {
return [$product->param1, $product->param2];
});
This will sort a collection by param2 first, and then by param1
Use a custom callback and return a composite property to sort on source
$posts = $posts->sortBy(function($post) {
return sprintf('%-12s%s', $post->column1, $post->column2);
});
Sort your array by column 1, then split it up by column 2 and then merge it again (untested).
$collection->sortByDesc('date');
$collection->groupBy('status');
$collection->keyBy('status');
EDIT: Also I'm not sure if sortByDesc('date') works with date strings.
Your expected result can be achieved like this.
$sorted = $collection
->sortByDesc('date')
->sortBy(function ($item) {
return 'pending' == $item['status'] ? 0 : 1;
})
->values();
To be more precise:
$collection= $collection->sort(
function ($a, $b) {
if(($a->status== $b->status) &&($a->status== 'pending')){
return ($a->date >= $b->date) ? -1 : 1;
}elseif($a->status== 'pending' && ($a->status!= $b->status)){
return 1;
}else{
return ($a->date <= $b->date) ? 1 : -1;
}
}
);
$collection= $collection->sortByDesc('status');

Grafana table that shows top 5 objects from an Array

I'm trying to create a table that shows the top 5 nested objects in an array.
My documents look something like this:
{
"_id": 1,
"workers": [
{
"worker_id": 1,
"units": [
{
"unit_id": 1,
"time": 100
},
{
"unit_id": 2,
"time": 200
},
{
"unit_id": 3,
"time": 300
},
{
"unit_id": 4,
"time": 400
}
]
},
{
"worker_id": 2,
"units": [
{
"unit_id": 11,
"time": 1000
},
{
"unit_id": 12,
"time": 200
},
{
"unit_id": 13,
"time": 300
},
{
"unit_id": 14,
"time": 350
}
]
}
]
}
I would like to have two columns in the table. One column with the _id of the document and the other with the unit_id. In the second column should be only the top five units that have the highest time.
Is this possible with Grafana?
For computing the top 5 entries from the nested Object, you can use simple-json-datasource plugin. You can create a simple Webapp which does the JSON Parsing logic and return the data in the format you want

Resources