Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node: ZINTER and ZUNION commands #1556

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#### Changes
* Node: Added ZINTER and ZUNION commands ([#1556](https://github.com/aws/glide-for-redis/pull/1556))
* Node: Added EXPIRETIME and PEXPIRETIME commands ([#2063](https://github.com/valkey-io/valkey-glide/pull/2063))
* Node: Added SORT commands ([#2028](https://github.com/valkey-io/valkey-glide/pull/2028))
* Node: Added LASTSAVE command ([#2059](https://github.com/valkey-io/valkey-glide/pull/2059))
Expand Down
134 changes: 132 additions & 2 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ import {
createZDiffStore,
createZDiffWithScores,
createZIncrBy,
createZInter,
createZInterCard,
createZInterstore,
createZLexCount,
Expand All @@ -180,6 +181,7 @@ import {
createZRevRankWithScore,
createZScan,
createZScore,
createZUnion,
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
} from "./Commands";
import {
ClosingError,
Expand Down Expand Up @@ -3051,9 +3053,9 @@ export class BaseClient {
* await client.zadd("key1", {"member1": 10.5, "member2": 8.2})
* await client.zadd("key2", {"member1": 9.5})
* await client.zinterstore("my_sorted_set", ["key1", "key2"]) // Output: 1 - Indicates that the sorted set "my_sorted_set" contains one element.
* await client.zrange_withscores("my_sorted_set", RangeByIndex(0, -1)) // Output: {'member1': 20} - "member1" is now stored in "my_sorted_set" with score of 20.
* await client.zrangeWithScores("my_sorted_set", RangeByIndex(0, -1)) // Output: {'member1': 20} - "member1" is now stored in "my_sorted_set" with score of 20.
* await client.zinterstore("my_sorted_set", ["key1", "key2"] , AggregationType.MAX ) // Output: 1 - Indicates that the sorted set "my_sorted_set" contains one element, and it's score is the maximum score between the sets.
* await client.zrange_withscores("my_sorted_set", RangeByIndex(0, -1)) // Output: {'member1': 10.5} - "member1" is now stored in "my_sorted_set" with score of 10.5.
* await client.zrangeWithScores("my_sorted_set", RangeByIndex(0, -1)) // Output: {'member1': 10.5} - "member1" is now stored in "my_sorted_set" with score of 10.5.
* ```
*/
public zinterstore(
Expand All @@ -3066,6 +3068,134 @@ export class BaseClient {
);
}

/**
* Computes the intersection of sorted sets given by the specified `keys` and returns a list of intersecting elements.
* To get the scores as well, see `zinterWithScores`.
* To store the result in a key as a sorted set, see `zinterStore`.
*
* When in cluster mode, all keys in `keys` must map to the same hash slot.
tjzhang-BQ marked this conversation as resolved.
Show resolved Hide resolved
*
* since - Valkey version 6.2.0.
shohamazon marked this conversation as resolved.
Show resolved Hide resolved
*
* See https://valkey.io/commands/zinter/ for more details.
tjzhang-BQ marked this conversation as resolved.
Show resolved Hide resolved
*
* @param keys - The keys of the sorted sets.
* @returns The resulting array of intersecting elements.
*
* since Valkey version 6.2.0.
tjzhang-BQ marked this conversation as resolved.
Show resolved Hide resolved
*
* @example
* ```typescript
* await client.zadd("key1", {"member1": 10.5, "member2": 8.2});
* await client.zadd("key2", {"member1": 9.5});
* const result = await client.zinter(["key1", "key2"]);
* console.log(result); // Output: ['member1']
* ```
*/
public zinter(keys: string[]): Promise<string[]> {
return this.createWritePromise(createZInter(keys));
}

/**
* Computes the intersection of sorted sets given by the specified `keys` and returns a list of intersecting elements with scores.
* To get the elements only, see `zinter`.
* To store the result in a key as a sorted set, see `zinterStore`.
*
* When in cluster mode, all keys in `keys` must map to the same hash slot.
tjzhang-BQ marked this conversation as resolved.
Show resolved Hide resolved
*
* See https://valkey.io/commands/zinter/ for more details.
tjzhang-BQ marked this conversation as resolved.
Show resolved Hide resolved
*
* @param keys - The keys of the sorted sets with possible formats:
* string[] - for keys only.
* KeyWeight[] - for weighted keys with score multipliers.
Comment on lines +3109 to +3110
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you format this as a list please?

* @param aggregationType - Specifies the aggregation strategy to apply when combining the scores of elements. See `AggregationType`.
* @returns The resulting sorted set with scores.
*
* since Valkey version 6.2.0.
*
* @example
* ```typescript
* await client.zadd("key1", {"member1": 10.5, "member2": 8.2});
* await client.zadd("key2", {"member1": 9.5});
* const result1 = await client.zinterWithScores(["key1", "key2"]);
* console.log(result1); // Output: {'member1': 20} - "member1" with score of 20 is the result
* const result2 = await client.zinterWithScores(["key1", "key2"], AggregationType.MAX)
* console.log(result2); // Output: {'member1': 10.5} - "member1" with score of 10.5 is the result.
* ```
*/
public zinterWithScores(
keys: string[] | KeyWeight[],
aggregationType?: AggregationType,
): Promise<Record<string, number>> {
return this.createWritePromise(
createZInter(keys, aggregationType, true),
);
}

/**
* Computes the union of sorted sets given by the specified `keys` and returns a list of union elements.
* To get the scores as well, see `zunionWithScores`.
*
* To store the result in a key as a sorted set, see `zunionStore`.
*
* When in cluster mode, all keys in `keys` must map to the same hash slot.
*
* since - Valkey version 6.2.0.
*
* See https://valkey.io/commands/zunion/ for more details.
tjzhang-BQ marked this conversation as resolved.
Show resolved Hide resolved
*
* @param keys - The keys of the sorted sets.
* @returns The resulting array of union elements.
*
* since Valkey version 6.2.0.
tjzhang-BQ marked this conversation as resolved.
Show resolved Hide resolved
*
* @example
* ```typescript
* await client.zadd("key1", {"member1": 10.5, "member2": 8.2});
* await client.zadd("key2", {"member1": 9.5});
* const result = await client.zunion(["key1", "key2"]);
* console.log(result); // Output: ['member1', 'member2']
* ```
*/
public zunion(keys: string[]): Promise<string[]> {
return this.createWritePromise(createZUnion(keys));
}

/**
* Computes the intersection of sorted sets given by the specified `keys` and returns a list of union elements with scores.
* To get the elements only, see `zunion`.
*
* When in cluster mode, all keys in `keys` must map to the same hash slot.
*
* See https://valkey.io/commands/zunion/ for more details.
adarovadya marked this conversation as resolved.
Show resolved Hide resolved
tjzhang-BQ marked this conversation as resolved.
Show resolved Hide resolved
*
* @param keys - The keys of the sorted sets with possible formats:
* string[] - for keys only.
* KeyWeight[] - for weighted keys with score multipliers.
* @param aggregationType - Specifies the aggregation strategy to apply when combining the scores of elements. See `AggregationType`.
* @returns The resulting sorted set with scores.
*
* since Valkey version 6.2.0.
*
* @example
* ```typescript
* await client.zadd("key1", {"member1": 10.5, "member2": 8.2});
* await client.zadd("key2", {"member1": 9.5});
* const result1 = await client.zunionWithScores(["key1", "key2"]);
* console.log(result1); // {'member1': 20, 'member2': 8.2}
* const result2 = await client.zunionWithScores(["key1", "key2"], "MAX");
* console.log(result2); // {'member1': 10.5, 'member2': 8.2}
* ```
*/
public zunionWithScores(
keys: string[] | KeyWeight[],
aggregationType?: AggregationType,
): Promise<Record<string, number>> {
return this.createWritePromise(
createZUnion(keys, aggregationType, true),
);
}

/**
* Returns a random member from the sorted set stored at `key`.
*
Expand Down
47 changes: 43 additions & 4 deletions node/src/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1406,16 +1406,51 @@ export function createZInterstore(
keys: string[] | KeyWeight[],
aggregationType?: AggregationType,
): command_request.Command {
const args = createZCmdStoreArgs(destination, keys, aggregationType);
const args = createZCmdArgs(keys, aggregationType, false, destination);
return createCommand(RequestType.ZInterStore, args);
}

function createZCmdStoreArgs(
destination: string,
/**
* @internal
*/
export function createZInter(
keys: string[] | KeyWeight[],
aggregationType?: AggregationType,
withScores?: boolean,
): command_request.Command {
const args = createZCmdArgs(keys, aggregationType, withScores);
return createCommand(RequestType.ZInter, args);
}

/**
* @internal
*/
export function createZUnion(
keys: string[] | KeyWeight[],
aggregationType?: AggregationType,
withScores?: boolean,
): command_request.Command {
const args = createZCmdArgs(keys, aggregationType, withScores);
return createCommand(RequestType.ZUnion, args);
}

adarovadya marked this conversation as resolved.
Show resolved Hide resolved
/**
* @internal
* Helper function for Zcommands (ZInter, ZinterStore, ZUnion..) that arranges arguments in the server's required order.
*/
function createZCmdArgs(
keys: string[] | KeyWeight[],
aggregationType?: AggregationType,
withscores?: boolean,
destination?: string,
): string[] {
const args: string[] = [destination, keys.length.toString()];
const args = [];

if (destination) {
args.push(destination);
}

args.push(keys.length.toString());

if (typeof keys[0] === "string") {
args.push(...(keys as string[]));
Expand All @@ -1430,6 +1465,10 @@ function createZCmdStoreArgs(
args.push("AGGREGATE", aggregationType);
}

if (withscores) {
args.push("WITHSCORES");
}

return args;
}

Expand Down
88 changes: 88 additions & 0 deletions node/src/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ import {
createZDiffStore,
createZDiffWithScores,
createZIncrBy,
createZInter,
createZInterCard,
createZInterstore,
createZLexCount,
Expand All @@ -211,6 +212,7 @@ import {
createZRevRankWithScore,
createZScan,
createZScore,
createZUnion,
} from "./Commands";
import { command_request } from "./ProtobufMessage";

Expand Down Expand Up @@ -1676,6 +1678,8 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
* KeyWeight[] - for weighted keys with score multipliers.
* @param aggregationType - Specifies the aggregation strategy to apply when combining the scores of elements. See `AggregationType`.
* Command Response - The number of elements in the resulting sorted set stored at `destination`.
*
* since Valkey version 6.2.0.
*/
public zinterstore(
destination: string,
Expand All @@ -1687,6 +1691,90 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
);
}

/**
* Computes the intersection of sorted sets given by the specified `keys` and returns a list of intersecting elements.
* To get the scores as well, see `zinter_withscores`.
* To store the result in a key as a sorted set, see `zinterstore`.
*
* When in cluster mode, all keys in `keys` must map to the same hash slot.
tjzhang-BQ marked this conversation as resolved.
Show resolved Hide resolved
*
* See https://valkey.io/commands/zinter/ for more details.
tjzhang-BQ marked this conversation as resolved.
Show resolved Hide resolved
*
* @param keys - The keys of the sorted sets.
* Command Response - The resulting array of intersecting elements.
*
* since Valkey version 6.2.0.
*/
public zinter(keys: string[]): T {
return this.addAndReturn(createZInter(keys));
}

/**
* Computes the intersection of sorted sets given by the specified `keys` and returns a list of intersecting elements with scores.
* To get the elements only, see `zinter`.
* To store the result in a key as a sorted set, see `zinterstore`.
*
* When in cluster mode, all keys in `keys` must map to the same hash slot.
*
* See https://valkey.io/commands/zinter/ for more details.
adarovadya marked this conversation as resolved.
Show resolved Hide resolved
tjzhang-BQ marked this conversation as resolved.
Show resolved Hide resolved
*
* @param keys - The keys of the sorted sets with possible formats:
* string[] - for keys only.
* KeyWeight[] - for weighted keys with score multipliers.
* @param aggregationType - Specifies the aggregation strategy to apply when combining the scores of elements. See `AggregationType`.
* Command Response - The resulting sorted set with scores.
*
* since Valkey version 6.2.0.
*/
public zinterWithScores(
keys: string[] | KeyWeight[],
aggregationType?: AggregationType,
): T {
return this.addAndReturn(createZInter(keys, aggregationType, true));
}

/**
* Computes the union of sorted sets given by the specified `keys` and returns a list of union elements.
* To get the scores as well, see `zunion_withscores`.
*
* To store the result in a key as a sorted set, see `zunionstore`.
*
* When in cluster mode, all keys in `keys` must map to the same hash slot.
*
* See https://valkey.io/commands/zunion/ for more details.
tjzhang-BQ marked this conversation as resolved.
Show resolved Hide resolved
*
* @param keys - The keys of the sorted sets.
* Command Response - The resulting array of union elements.
*
* since Valkey version 6.2.0.
*/
public zunion(keys: string[]): T {
return this.addAndReturn(createZUnion(keys));
}

/**
* Computes the intersection of sorted sets given by the specified `keys` and returns a list of union elements with scores.
* To get the elements only, see `zunion`.
*
* When in cluster mode, all keys in `keys` must map to the same hash slot.
*
* See https://valkey.io/commands/zunion/ for more details.
tjzhang-BQ marked this conversation as resolved.
Show resolved Hide resolved
*
* @param keys - The keys of the sorted sets with possible formats:
* string[] - for keys only.
* KeyWeight[] - for weighted keys with score multipliers.
* @param aggregationType - Specifies the aggregation strategy to apply when combining the scores of elements. See `AggregationType`.
* Commnd Response - The resulting sorted set with scores.
*
* since Valkey version 6.2.0.
*/
public zunionWithScores(
keys: string[] | KeyWeight[],
aggregationType?: AggregationType,
): T {
return this.addAndReturn(createZUnion(keys, aggregationType, true));
}

/**
* Returns a random member from the sorted set stored at `key`.
*
Expand Down
4 changes: 4 additions & 0 deletions node/tests/GlideClusterClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,12 @@ describe("GlideClusterClient", () => {
client.smove("abc", "zxy", "value"),
client.renamenx("abc", "zxy"),
client.sinter(["abc", "zxy", "lkn"]),
client.zinter(["abc", "zxy", "lkn"]),
client.zinterWithScores(["abc", "zxy", "lkn"]),
client.sinterstore("abc", ["zxy", "lkn"]),
client.zinterstore("abc", ["zxy", "lkn"]),
client.zunion(["abc", "zxy", "lkn"]),
client.zunionWithScores(["abc", "zxy", "lkn"]),
client.sunionstore("abc", ["zxy", "lkn"]),
client.sunion(["abc", "zxy", "lkn"]),
client.pfcount(["abc", "zxy", "lkn"]),
Expand Down
Loading
Loading