rethinkdb: secondary compound indexes / aggregation queries and intermediate documents generation - indexing

Let's assume such table content where for the same product_id, we have as many rows than updates during status==1 (published) and finally status==0 (unpublished) and then becomes==2 (deleted)
{id: <auto>, product_id: 1, last_updated: 2015-12-1, status: 1, price: 1}
{id: <auto>, product_id: 2, last_updated: 2015-12-1, status: 1, price: 10}
{id: <auto>, product_id: 1, last_updated: 2015-12-2, status: 1, price: 2}
{id: <auto>, product_id: 1, last_updated: 2015-12-3, status: 0, price: 2}
{id: <auto>, product_id: 2, last_updated: 2015-12-2, status: 0, price: 10}
{id: <auto>, product_id: 3, last_updated: 2015-12-2, status: 1, price: 123}
{id: <auto>, product_id: 1, last_updated: 2015-12-4, status: 2, price: 2}
{id: <auto>, product_id: 2, last_updated: 2015-12-4, status: 2, price: 10}
Now, I am trying to find a way, maybe using a secondary compound index, do get for example, given a date like in col1 (using r.time)
DATE STATUS==1 STATUS==0 STATUS==2
2015-12-1 [101, 102] [] []
2015-12-2 [103, 106] [105] []
2015-12-3 [106] [104, 105] []
2015-12-4 [] [] [107, 108]
The difficulty here, is that a product_id document is still to be considered as the most recent status as long as its last_updated date is less or equal to the provided date.
I try by grouping by product_id, then take the max('last_updated'), then only keep each reduction unique document if status==1
I have in mind to have an index for each status / given_date
Or another solution, would be to insert in another table the result of an aggregation which would only store a unique document per date, containing all the initial documents ids matching the same criteria, and so on...
And then later perform joins using these intermediate records to fetch the values of each product_id at the given date/status.
something like:
{
date: <date_object>,
documents: [
{id: document_id, status: 1},
{id: document_id, status: 1},
{id: document_id, status: 2},
{id: document_id, status: 0},
...
]
}
Please advise
Edit 1:
This is an example of a query I try to run to analyse my data, here it is for example to get an overview of the statuses for each group with more than 1 document:
r.db('test').table('products_10k_sample')
.group({index: 'product_id'})
.orderBy(r.desc('last_updated'))
.ungroup()
.map(function(x){
return r.branch(
x('reduction').count().gt(1),
x('reduction').map(function(m){
return [m('last_updated').toISO8601(), m('status'), m('product_id')]
}),
null
)
})

Related

Group By with multiple Objects vb.net

I have a list as following
list1 = [
{meal: {id: 1, version: 0}, type: {id: 2, version: 0}, adjCount: 1, systemCount: 0},
{meal: {id: 1, version: 0}, type: {id: 2, version: 0}, adjCount: 2, systemCount: 0},
{meal: {id: 2, version: 0}, type: {id: 1, version: 0}, adjCount: 4, systemCount: 0},
{meal: {id: 2, version: 0}, type: {id: 1, version: 0}, adjCount: 7, systemCount: 0},
]
I'm looking for a result such as it returns both mealId and type id with it's respective totals
As
{meal: {id: 1, version: 0}, type: {id: 2, version: 0}, adjCount: 3, systemCount: 0},
{meal: {id: 2, version: 0}, type: {id: 1, version: 0}, adjCount: 11, systemCount: 0}
I tried Using Linq with following code
List.GroupBy(Function(myItem) New MyObject With {.mealTypeId = myItem.Meal.Id, .countTypeId = MyItem.Count.Id}).
Select(Function(g) New With
{
.MealTypeId = g.Key.MealTypeId,
.CountTypeId = g.Key.CountTypeId,
.AdjustmentCount = g.Sum(Function(i) i.AdjustmentCount),
.SystemCount = g.Sum(Function(i) i.SystemCount)
}
but it doesn't return the expected output. Any Help will be greatly appreciated, I very rarely ask questions here so please forgive any mistakes I might have done in describing the issue.

How do I insert and update array columns in Node-Postgres?

I have the following table in Postgres:
_id: integer, user_id: integer, items: Array
I wish to insert the following into the table:
1, 1, [{productId: 1, size: 'large', quantity: 5}]
Next I wish to update the row with the following:
1, 1, [{productId: 1, size: 'small', quantity: 3}]
How do I do this in node-postgres?
Pseudocode:
update cart
set items.quantity = 3
where cart._id = 1
and cart.items.product_id = 1
and cart.items.size='large'

Postgresql batch update

How to batch update the following sample more efficiently.
users = [{id: 424, pos: 1}, {id: 23, pos: 2}, {id: 55, pos: 3}, ...]
//currently loop updating each {i}:
UPDATE users SET position = i.pos WHERE id = i.id
You can use unnest():
update users u
set position = user.pos
from (values ([{id: 424, pos: 1}, {id: 23, pos: 2}, {id: 55, pos: 3}, ...])
) v(users) cross join lateral
unnest(users) user
where u.id = user.id

Lodash: how to find max and min values of each id

My data array is
array = [{id: 2, name: "kent", status_id: 2, date_1: "2018-08-09", date_2: "2018-07-06"},{id: 2, name: "kent", status_id: 10, date_1: "2018-01-09", date_2: "2018-09-06"},{id: 3, name: "tracy", status_id: 2, date_1: "2018-05-03", date_2: "2018-10-02"},{id: 3, name: "tracy", status_id: 2, date_1: "2018-01-10", date_2: "2018-09-12"},{id: 3, name: "tracy", status_id: 10, date_1: "2018-02-10", date_2: "2018-09-02"},{id: 4, name: "lucy", status_id: 10, date_1: "2018-12-10", date_2: "2018-08-09"},{id: 5, name: "steve", status_id: 10, date_1: "2018-12-7", date_2: "2018-04-01"}]
If the id =2 I would like to find max(date_1) & min(date_2) for each id=2. Like my output should be,
id
2 max(date_1) min(date_2)
3 max(date_1) min(date_2)
4 max(date_1) min(date_2)
5 max(date_1) min(date_2)
I am using Lodash library. I would appreciate the help.
You can first groupBy id and then map each grouped values using mapValues since that will be a object. while mapping the grouped values you can use _.maxBy and _minBy to find max and min
var array = [{"id":2,"name":"kent","status_id":2,"date_1":"2018-08-09","date_2":"2018-07-06"},{"id":2,"name":"kent","status_id":10,"date_1":"2018-01-09","date_2":"2018-09-06"},{"id":3,"name":"tracy","status_id":2,"date_1":"2018-05-03","date_2":"2018-10-02"},{"id":3,"name":"tracy","status_id":2,"date_1":"2018-01-10","date_2":"2018-09-12"},{"id":3,"name":"tracy","status_id":10,"date_1":"2018-02-10","date_2":"2018-09-02"},{"id":4,"name":"lucy","status_id":10,"date_1":"2018-12-10","date_2":"2018-08-09"},{"id":5,"name":"steve","status_id":10,"date_1":"2018-12-7","date_2":"2018-04-01"}]
var res =
_(array)
.groupBy('id')
.mapValues(a => ({
max: _.maxBy(a, 'date_1').date_1,
min: _.minBy(a, 'date_2').date_2
})).value();
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

objective-c equivalent to group by in groovy

Source array:
[ { a: 1, b: 1}, { a: 1, b: 2}, { a: 2, b: 3} ]
Target dictionary:
{ 1: [{a: 1, b: 1}, {a: 1, b: 2}], 2: [{ a: 2, b: 3}] }
So i want to have the objects in the source array grouped by their value of a.
In groovy it's done using array.groupBy({ it.a }). Is there a nice equivalent in objective-c?