If you need to sort values before pagination, you can include index bindings in the values and your index will sort on them.
It’s not really possible to do this on the index level at the moment, because I can’t do something like:
CreateIndex({
name: 'sampleIndex',
source: {
collection: Collection('sampleCollection'),
fields: {
computedField: Query(
Lambda(
['document', 'userInputArgument'] // <--- notice userInputArgument has to be given to this lambda,
Subtract(
Select(['data', 'amount'], Var('document')),
Var('userInputArgument')
)
)
)
}
},
values: [
{ binding: 'computedField' } // sort by the computed field
]
})
Notice that I passed an argument to the binding
, I can’t find that in the documentation so I’m not sure how that can be achieved, because I need that userInputFIeld
to compute the difference, right?
Reason why I want it to be tied as a condition to the pagination
Consider the following data:
[
{
amount: 1000,
createdAt: 'some date'
},
{
amount: 594,
createdAt: 'some date'
},
{
amount: 995,
createdAt: 'some date'
},
{
amount: 104,
createdAt: 'some date'
},
{
amount: 607,
createdAt: 'some date'
},
{
amount: 7896,
createdAt: 'some date'
},
{
amount: 107,
createdAt: 'some date'
},
{
amount: 96,
createdAt: 'some date'
},
{
amount: 12,
createdAt: 'some date'
},
{
amount: 876,
createdAt: 'some date'
},
{
amount: 346,
createdAt: 'some date'
}
]
and userInput
of 5
to compute the difference.
By default, the way that the data sits in the collection is that it’s sorted on when it was created, pretty much like how array.push()
(correct me if I’m wrong).
So If I do Paginate
with size of 3 and then do the sorting AFTER the data has been fetched so the Paginate is not aware of it.
What will happen is I will get these results:
[
{
amount: 1000,
createdAt: 'some date'
},
{
amount: 594,
createdAt: 'some date'
},
{
amount: 995,
createdAt: 'some date'
}
]
and then sort them to get:
[
{
amount: 594,
difference: 589,
createdAt: 'some date'
},
{
amount: 1000,
difference: 995,
createdAt: 'some date'
},
{
amount: 995,
difference: 990,
createdAt: 'some date'
}
]
Well now this is a bad thing because paginate has skipped on the other data, because the next page will look like (after already sorted)
[
{
amount: 104,
difference: 99,
createdAt: 'some date'
},
{
amount: 607,
difference: 602,
createdAt: 'some date'
},
{
amount: 7896,
difference: 7891,
createdAt: 'some date'
}
]
So the whole data is now incorrectly sorted, why? Because now the whole data (from page 1 to 2) look like:
[
{
amount: 594,
difference: 589,
createdAt: 'some date'
},
{
amount: 1000,
difference: 995,
createdAt: 'some date'
},
{
amount: 995,
difference: 990,
createdAt: 'some date'
},
{
amount: 104,
difference: 99,
createdAt: 'some date'
},
{
amount: 607,
difference: 602,
createdAt: 'some date'
},
{
amount: 7896,
difference: 7891,
createdAt: 'some date'
}
]
Notice how they are no longer in the right order?
The correct order would have been:
Page 1:
[
{
amount: 12,
difference: 7,
createdAt: "some date",
},
{
amount: 96,
difference: 91,
createdAt: "some date",
},
{
amount: 104,
difference: 99,
createdAt: "some date",
}
]
Page 2
[
{
amount: 107,
difference: 102,
createdAt: "some date",
},
{
amount: 346,
difference: 341,
createdAt: "some date",
},
{
amount: 594,
difference: 589,
createdAt: "some date",
}
]
So combining the 2 pages:
[
{
amount: 12,
difference: 7,
createdAt: "some date",
},
{
amount: 96,
difference: 91,
createdAt: "some date",
},
{
amount: 104,
difference: 99,
createdAt: "some date",
},
{
amount: 107,
difference: 102,
createdAt: "some date",
},
{
amount: 346,
difference: 341,
createdAt: "some date",
},
{
amount: 594,
difference: 589,
createdAt: "some date",
}
]
They are still in the correct order.
In MySQL, this would translate to roughly something like:
select *, table.amount - 5 as difference from table order by difference asc
forgive me if the syntax is incorrect, I’ve forgotten SQL
For more context
These data are just dummy data that represents what I want to do, in reality, I have a collection of events
or meetups
and I’m fetching them and displaying them to the user, I want to sort them, in ascending order, based on distance of the current location of the user and the venue of the event. That distance
is the computed field. I simply made a simpler version of it as the topic to remove unnecessary complications.