redis sort by multi fields - sorting

It's easy to use sql to query with multi sort fields.For example:
select * from user order by score desc,name desc
with two fields sort(score,name).
how should do this in redis?

Use sorted set of redis which is sorted by score. You have to prepare score according to your needs.
finalScore = score*MAX_NAME_VALUE + getIntRepresentation(name)
//MAX_NAME_VALUE is the maximum value returned by getIntRepresentation() method
and then use
zadd myset finalScore value
and the just use
zrevrange myset 0 10

Related

Order DynamoDB paginated Boto scan by order

I have clear code for ordering a DynamoDB scan by ascending or descending using the
response = table.query(
ScanIndexForward=False # true = ascending, false = descending
)
argument. Likewise I have the boto paginator for paginating responses using the following:
paginator = dynamodb.get_paginator('scan')
response_iterator = paginator.paginate(
TableName=table.table_name,
PaginationConfig={"MaxItems": 25, "PageSize": 1}
)
But I am unable to find an optional argument or method to do both. The order returned by the paginator class appears to be random.
Is there a way to order the notifications by ascending or descending and then split into paginated shards?
I have investigated the optional arguments passed to the paginator scan in the documentation but ScanIndexForward is not an optional argument on SCAN and there is no ASC or DESC option in the conditions that can be passed to ScanFilter.
The table is created within the python CDK with the following partition and sort keys:
dynamodb.Table(
self,
"NotificationsTable",
partition_key=dynamodb.Attribute(
name="_id", type=dynamodb.AttributeType.STRING
),
sort_key=dynamodb.Attribute(
name="Date", type=dynamodb.AttributeType.NUMBER
)
)
You cannot order a Scan operation as it spans multiple partition keys, each pk will return at random, but in order by its accompanying sort-key. Your original request was a Query with ScanIndexForward, this only returns a single partition key ordered by the sort key.

How to sort in laravel eloquent?

When i sort it gives me data like this:
10
19
100
20
abc
fff
How can i properly sort it like this:
10
19
20
100
abc
fff
Model::orderBy('text','asc')->get();
The sortBy method sorts the collection by the given key. The sorted collection keeps the original array keys :
$q = Model::orderBy('text','asc')->get();
$sorted = $q->sortBy('text');
Alternatively, you can use sortByDesc() method. sortDesc()
method will sort the collection in the opposite order as the sort() method.
you need to declare the field in your table as an Integer and not as a String.
If a field is of String type its values are evaluated like this:
"100" < "20"
But if the field is of Integer type, eloquent evaluate like this:
20 < 100
Hi.
You can also use sortBy to sort your data with passing closer to your query, have added an example you can use it.
class::all()->sortBy(function ($query){
return $query->Your_Field_Name;
});
It will also depend on what data type you have chosen in your migration.
you can sort based on the column if it can be casted to UNSIGNED number, otherwise sort by the column it self:
Model::orderByRaw('CAST(text AS UNSIGNED), text')->get();

How to filter clickhouse table by array column contents?

I have a clickhouse table that has one Array(UInt16) column. I want to be able to filter results from this table to only get rows where the values in the array column are above a threshold value. I've been trying to achieve this using some of the array functions (arrayFilter and arrayExists) but I'm not familiar enough with the SQL/Clickhouse query syntax to get this working.
I've created the table using:
CREATE TABLE IF NOT EXISTS ArrayTest (
date Date,
sessionSecond UInt16,
distance Array(UInt16)
) Engine = MergeTree(date, (date, sessionSecond), 8192);
Where the distance values will be distances from a certain point at a certain amount of seconds (sessionSecond) after the date. I've added some sample values so the table looks like the following:
Now I want to get all rows which contain distances greater than 7. I found the array operators documentation here and tried the arrayExists function but it's not working how I'd expect. From the documentation, it says that this function "Returns 1 if there is at least one element in 'arr' for which 'func' returns something other than 0. Otherwise, it returns 0". But when I run the query below I get three zeros returned where I should get a 0 and two ones:
SELECT arrayExists(
val -> val > 7,
arrayEnumerate(distance))
FROM ArrayTest;
Eventually I want to perform this select and then join it with the table contents to only return rows that have an exists = 1 but I need this first step to work before that. Am I using the arrayExists wrong? What I found more confusing is that when I change the comparison value to 2 I get all 1s back. Can this kind of filtering be achieved using the array functions?
Thanks
You can use arrayExists in the WHERE clause.
SELECT *
FROM ArrayTest
WHERE arrayExists(x -> x > 7, distance) = 1;
Another way is to use ARRAY JOIN, if you need to know which values is greater than 7:
SELECT d, distance, sessionSecond
FROM ArrayTest
ARRAY JOIN distance as d
WHERE d > 7
I think the reason why you get 3 zeros is that arrayEnumerate enumerates over the array indexes not array values, and since none of your rows have more than 7 elements arrayEnumerates results in 0 for all the rows.
To make this work,
SELECT arrayExists(
val -> distance[val] > 7,
arrayEnumerate(distance))
FROM ArrayTest;

Cloudant couchdb query custom sort

I want to sort the results of couchdb query a.k.a mango queries based on custom sort. I need custom sort because if Status can be one of the following:
Active = 1
Sold = 2
Contingent = 4
Pending = 3
I want to sort the results on Status but not in an alphabetical order, rather my own weightage I assign to each value which can be seen in the above list. Here's the selector for Status query I'm using:
{type:"Property", Status:{"$or":[{$eq: "Pending"}, {$eq:"Active"}, {$eq: "Sold"}]}}
If I use the sort array in my json with Status I think it'll sort alphabetically which I don't want.
You are actually looking for results based on "Status". You can create a view similar to this:
function(doc) { if (doc.type == "Property") { emit(doc.Status, doc);}}
When you use it, invoke it 4 times in the order you need and you'll get the result you need. This would eliminate the need to sort.

How to retrieve the last 100 documents with a MongoDB/Moped query?

I am using the Ruby Mongoid gem and trying to create a query to retrieve the last 100 documents from a collection. Rather than using Mongoid, I would like to create the query using the underlying driver (Moped). The Moped documentation only mentions how to retrieve the first 100 records:
session[:my_collection].find.limit(100)
How can I retrieve the last 100?
I have found a solution, but you will need to sort collection in descending order. If you have a field id or date you would do:
Method .sort({fieldName: 1 or -1})
The 1 will sort ascending (oldest to newest), -1 will sort descending (newest to oldest). This will reverse entries of your collection.
session[:my_collection].find().sort({id:-1}) or
session[:my_collection].find().sort({date:-1})
If your collection contain field id (_id) that identifier have a date embedded, so you can use
session[:my_collection].find().sort({_id:-1})
In accordance with your example using .limit() the complete query will be:
session[:my_collection].find().sort({id:-1}).limit(100);
Technically that query isn't finding the first 100, that's essentially finding 100 random documents because you haven't specified an order. If you want the first then you'd have to say explicitly sort them:
session[:my_collection].find.sort(:some_field => 1).limit(100)
and to reverse the order to find the last 100 with respect to :some_field:
session[:my_collection].find.sort(:some_field => -1).limit(100)
# -----------------------------------------------^^
Of course you have decide what :some_field is going to be so the "first" and "last" make sense for you.
If you want them sorted by :some_field but want to peel off the last 100 then you could reverse them in Ruby:
session[:my_collection].find
.sort(:some_field => -1)
.limit(100)
.reverse
or you could use use count to find out how many there are then skip to offset into the results:
total = session[:my_collection].find.count
session[:my_collection].find
.sort(:some_field => 1)
.skip(total - 100)
You'd have to check that total >= 100 and adjust the skip argument if it wasn't of course. I suspect that the first solution would be faster but you should benchmark it with your data to see what reality says.

Resources