From 4f0b50b7a7812f3aacb4443d6e62eb3c8727c93c Mon Sep 17 00:00:00 2001 From: Andy Stark Date: Mon, 28 Jul 2025 11:46:51 +0100 Subject: [PATCH 1/4] DOC-5501 Python prob examples --- content/develop/clients/redis-py/prob.md | 185 +++++++++++++++++++++-- 1 file changed, 173 insertions(+), 12 deletions(-) diff --git a/content/develop/clients/redis-py/prob.md b/content/develop/clients/redis-py/prob.md index 91df1ffca5..2c1a72af66 100644 --- a/content/develop/clients/redis-py/prob.md +++ b/content/develop/clients/redis-py/prob.md @@ -99,16 +99,45 @@ add. The following example adds some names to a Bloom filter representing a list of users and checks for the presence or absence of users in the list. Note that you must use the `bf()` method to access the Bloom filter commands. -{{< clients-example home_prob_dts bloom Python >}} -{{< /clients-example >}} +```py +res1 = r.bf().madd("recorded_users", "andy", "cameron", "david", "michelle") +print(res1) # >>> [1, 1, 1, 1] + +res2 = r.bf().exists("recorded_users", "cameron") +print(res2) # >>> 1 + +res3 = r.bf().exists("recorded_users", "kaitlyn") +print(res3) # >>> 0 +``` + A Cuckoo filter has similar features to a Bloom filter, but also supports a deletion operation to remove hashes from a set, as shown in the example below. Note that you must use the `cf()` method to access the Cuckoo filter commands. -{{< clients-example home_prob_dts cuckoo Python >}} -{{< /clients-example >}} +```py +res4 = r.cf().add("other_users", "paolo") +print(res4) # >>> 1 + +res5 = r.cf().add("other_users", "kaitlyn") +print(res5) # >>> 1 + +res6 = r.cf().add("other_users", "rachel") +print(res6) # >>> 1 + +res7 = r.cf().mexists("other_users", "paolo", "rachel", "andy") +print(res7) # >>> [1, 1, 0] + +res8 = r.cf().delete("other_users", "paolo") +print(res8) # >>> 1 + +res9 = r.cf().exists("other_users", "paolo") +print(res9) # >>> 0 +``` + Which of these two data types you choose depends on your use case. Bloom filters are generally faster than Cuckoo filters when adding new items, @@ -128,8 +157,27 @@ You can also merge two or more HyperLogLogs to find the cardinality of the [union](https://en.wikipedia.org/wiki/Union_(set_theory)) of the sets they represent. -{{< clients-example home_prob_dts hyperloglog Python >}} -{{< /clients-example >}} +```py +res10 = r.pfadd("group:1", "andy", "cameron", "david") +print(res10) # >>> 1 + +res11 = r.pfcount("group:1") +print(res11) # >>> 3 + +res12 = r.pfadd("group:2", "kaitlyn", "michelle", "paolo", "rachel") +print(res12) # >>> 1 + +res13 = r.pfcount("group:2") +print(res13) # >>> 4 + +res14 = r.pfmerge("both_groups", "group:1", "group:2") +print(res14) # >>> True + +res15 = r.pfcount("both_groups") +print(res15) # >>> 7 +``` + The main benefit that HyperLogLogs offer is their very low memory usage. They can count up to 2^64 items with less than @@ -169,8 +217,35 @@ a Count-min sketch object, add data to it, and then query it. Note that you must use the `cms()` method to access the Count-min sketch commands. -{{< clients-example home_prob_dts cms Python >}} -{{< /clients-example >}} +```py +# Specify that you want to keep the counts within 0.01 +# (1%) of the true value with a 0.005 (0.5%) chance +# of going outside this limit. +res16 = r.cms().initbyprob("items_sold", 0.01, 0.005) +print(res16) # >>> True + +# The parameters for `incrby()` are two lists. The count +# for each item in the first list is incremented by the +# value at the same index in the second list. +res17 = r.cms().incrby( + "items_sold", + ["bread", "tea", "coffee", "beer"], # Items sold + [300, 200, 200, 100] +) +print(res17) # >>> [300, 200, 200, 100] + +res18 = r.cms().incrby( + "items_sold", + ["bread", "coffee"], + [100, 150] +) +print(res18) # >>> [400, 350] + +res19 = r.cms().query("items_sold", "bread", "tea", "coffee", "beer") +print(res19) # >>> [400, 200, 350, 100] +``` + The advantage of using a CMS over keeping an exact count with a [sorted set]({{< relref "/develop/data-types/sorted-sets" >}}) @@ -202,8 +277,52 @@ shows how to merge two or more t-digest objects to query the combined data set. Note that you must use the `tdigest()` method to access the t-digest commands. -{{< clients-example home_prob_dts tdigest Python >}} -{{< /clients-example >}} +```py +res20 = r.tdigest().create("male_heights") +print(res20) # >>> True + +res21 = r.tdigest().add( + "male_heights", + [175.5, 181, 160.8, 152, 177, 196, 164] +) +print(res21) # >>> OK + +res22 = r.tdigest().min("male_heights") +print(res22) # >>> 152.0 + +res23 = r.tdigest().max("male_heights") +print(res23) # >>> 196.0 + +res24 = r.tdigest().quantile("male_heights", 0.75) +print(res24) # >>> 181 + +# Note that the CDF value for 181 is not exactly +# 0.75. Both values are estimates. +res25 = r.tdigest().cdf("male_heights", 181) +print(res25) # >>> [0.7857142857142857] + +res26 = r.tdigest().create("female_heights") +print(res26) # >>> True + +res27 = r.tdigest().add( + "female_heights", + [155.5, 161, 168.5, 170, 157.5, 163, 171] +) +print(res27) # >>> OK + +res28 = r.tdigest().quantile("female_heights", 0.75) +print(res28) # >>> [170] + +res29 = r.tdigest().merge( + "all_heights", 2, "male_heights", "female_heights" +) +print(res29) # >>> OK + +res30 = r.tdigest().quantile("all_heights", 0.75) +print(res30) # >>> [175.5] +``` + A t-digest object also supports several other related commands, such as querying by rank. See the @@ -225,5 +344,47 @@ top *k* items and query whether or not a given item is in the list. Note that you must use the `topk()` method to access the Top-K commands. -{{< clients-example home_prob_dts topk Python >}} -{{< /clients-example >}} +```py +# The `reserve()` method creates the Top-K object with +# the given key. The parameters are the number of items +# in the ranking and values for `width`, `depth`, and +# `decay`, described in the Top-K reference page. +res31 = r.topk().reserve("top_3_songs", 3, 7, 8, 0.9) +print(res31) # >>> True + +# The parameters for `incrby()` are two lists. The count +# for each item in the first list is incremented by the +# value at the same index in the second list. +res32 = r.topk().incrby( + "top_3_songs", + [ + "Starfish Trooper", + "Only one more time", + "Rock me, Handel", + "How will anyone know?", + "Average lover", + "Road to everywhere" + ], + [ + 3000, + 1850, + 1325, + 3890, + 4098, + 770 + ] +) +print(res32) +# >>> [None, None, None, 'Rock me, Handel', 'Only one more time', None] + +res33 = r.topk().list("top_3_songs") +print(res33) +# >>> ['Average lover', 'How will anyone know?', 'Starfish Trooper'] + +res34 = r.topk().query( + "top_3_songs", "Starfish Trooper", "Road to everywhere" +) +print(res34) # >>> [1, 0] +``` + From 23cc357211d5bb899e3b0aae8b28e05e91d66422 Mon Sep 17 00:00:00 2001 From: Andy Stark Date: Mon, 28 Jul 2025 12:03:02 +0100 Subject: [PATCH 2/4] DOC-5501 C# prob examples --- content/develop/clients/dotnet/prob.md | 215 +++++++++++++++++++++++-- 1 file changed, 202 insertions(+), 13 deletions(-) diff --git a/content/develop/clients/dotnet/prob.md b/content/develop/clients/dotnet/prob.md index 2b6b04d092..526d629154 100644 --- a/content/develop/clients/dotnet/prob.md +++ b/content/develop/clients/dotnet/prob.md @@ -99,16 +99,49 @@ add. The following example adds some names to a Bloom filter representing a list of users and checks for the presence or absence of users in the list. Note that you must use the `BF()` method to access the Bloom filter commands. -{{< clients-example home_prob_dts bloom "C#" >}} -{{< /clients-example >}} +```cs +bool[] res1 = db.BF().MAdd( + "recorded_users", "andy", "cameron", "david", "michelle" +); +Console.WriteLine(string.Join(", ", res1)); +// >>> true, true, true, true + +bool res2 = db.BF().Exists("recorded_users", "cameron"); +Console.WriteLine(res2); // >>> true + +bool res3 = db.BF().Exists("recorded_users", "kaitlyn"); +Console.WriteLine(res3); // >>> false +``` + A Cuckoo filter has similar features to a Bloom filter, but also supports a deletion operation to remove hashes from a set, as shown in the example below. Note that you must use the `CF()` method to access the Cuckoo filter commands. -{{< clients-example home_prob_dts cuckoo "C#" >}} -{{< /clients-example >}} +```cs +bool res4 = db.CF().Add("other_users", "paolo"); +Console.WriteLine(res4); // >>> true + +bool res5 = db.CF().Add("other_users", "kaitlyn"); +Console.WriteLine(res5); // >>> true + +bool res6 = db.CF().Add("other_users", "rachel"); +Console.WriteLine(res6); // >>> true + +bool[] res7 = db.CF().MExists("other_users", "paolo", "rachel", "andy"); +Console.WriteLine(string.Join(", ", res7)); +// >>> true, true, false + +bool res8 = db.CF().Del("other_users", "paolo"); +Console.WriteLine(res8); // >>> true + +bool res9 = db.CF().Exists("other_users", "paolo"); +Console.WriteLine(res9); // >>> false +``` + Which of these two data types you choose depends on your use case. Bloom filters are generally faster than Cuckoo filters when adding new items, @@ -128,8 +161,35 @@ You can also merge two or more HyperLogLogs to find the cardinality of the [union](https://en.wikipedia.org/wiki/Union_(set_theory)) of the sets they represent. -{{< clients-example home_prob_dts hyperloglog "C#" >}} -{{< /clients-example >}} +```cs +bool res10 = db.HyperLogLogAdd( + "group:1", + new RedisValue[] { "andy", "cameron", "david" } +); +Console.WriteLine(res10); // >>> true + +long res11 = db.HyperLogLogLength("group:1"); +Console.WriteLine(res11); // >>> 3 + +bool res12 = db.HyperLogLogAdd( + "group:2", + new RedisValue[] { "kaitlyn", "michelle", "paolo", "rachel" } +); +Console.WriteLine(res12); // >>> true + +long res13 = db.HyperLogLogLength("group:2"); +Console.WriteLine(res13); // >>> 4 + +db.HyperLogLogMerge( + "both_groups", + "group:1", "group:2" +); + +long res14 = db.HyperLogLogLength("both_groups"); +Console.WriteLine(res14); // >>> 7 +``` + The main benefit that HyperLogLogs offer is their very low memory usage. They can count up to 2^64 items with less than @@ -168,9 +228,44 @@ of going outside this limit. The example below shows how to create a Count-min sketch object, add data to it, and then query it. Note that you must use the `CMS()` method to access the Count-min sketch commands. - -{{< clients-example home_prob_dts cms "C#" >}} -{{< /clients-example >}} +```cs +// Specify that you want to keep the counts within 0.01 +// (1%) of the true value with a 0.005 (0.5%) chance +// of going outside this limit. +bool res15 = db.CMS().InitByProb("items_sold", 0.01, 0.005); +Console.WriteLine(res15); // >>> true + +long[] res16 = db.CMS().IncrBy( + "items_sold", + new Tuple[]{ + new("bread", 300), + new("tea", 200), + new("coffee", 200), + new("beer", 100) + } +); +Console.WriteLine(string.Join(", ", res16)); +// >>> 300, 200, 200, 100 + +long[] res17 = db.CMS().IncrBy( + "items_sold", + new Tuple[]{ + new("bread", 100), + new("coffee", 150), + } +); +Console.WriteLine(string.Join(", ", res17)); +// >>> 400, 350 + +long[] res18 = db.CMS().Query( + "items_sold", + "bread", "tea", "coffee", "beer" +); +Console.WriteLine(string.Join(", ", res18)); +// >>> 400, 200, 350, 100 +``` + The advantage of using a CMS over keeping an exact count with a [sorted set]({{< relref "/develop/data-types/sorted-sets" >}}) @@ -202,8 +297,53 @@ shows how to merge two or more t-digest objects to query the combined data set. Note that you must use the `TDIGEST()` method to access the t-digest commands. -{{< clients-example home_prob_dts tdigest "C#" >}} -{{< /clients-example >}} +```cs +bool res19 = db.TDIGEST().Create("male_heights"); +Console.WriteLine(res19); // >>> true + +bool res20 = db.TDIGEST().Add( + "male_heights", + 175.5, 181, 160.8, 152, 177, 196, 164 +); +Console.WriteLine(res20); // >>> true + +double res21 = db.TDIGEST().Min("male_heights"); +Console.WriteLine(res21); // >>> 152.0 + +double res22 = db.TDIGEST().Max("male_heights"); +Console.WriteLine(res22); // >>> 196.0 + +double[] res23 = db.TDIGEST().Quantile("male_heights", 0.75); +Console.WriteLine(string.Join(", ", res23)); // >>> 181.0 + +// Note that the CDF value for 181.0 is not exactly +// 0.75. Both values are estimates. +double[] res24 = db.TDIGEST().CDF("male_heights", 181.0); +Console.WriteLine(string.Join(", ", res24)); // >>> 0.7857142857142857 + +bool res25 = db.TDIGEST().Create("female_heights"); +Console.WriteLine(res25); // >>> true + +bool res26 = db.TDIGEST().Add( + "female_heights", + 155.5, 161, 168.5, 170, 157.5, 163, 171 +); +Console.WriteLine(res26); // >>> true + +double[] res27 = db.TDIGEST().Quantile("female_heights", 0.75); +Console.WriteLine(string.Join(", ", res27)); // >>> 170.0 + +// Specify 0 for `compression` and false for `override`. +bool res28 = db.TDIGEST().Merge( + "all_heights", 0, false, "male_heights", "female_heights" +); +Console.WriteLine(res28); // >>> true + +double[] res29 = db.TDIGEST().Quantile("all_heights", 0.75); +Console.WriteLine(string.Join(", ", res29)); // >>> 175.5 +``` + A t-digest object also supports several other related commands, such as querying by rank. See the @@ -225,5 +365,54 @@ top *k* items and query whether or not a given item is in the list. Note that you must use the `TOPK()` method to access the Top-K commands. -{{< clients-example home_prob_dts topk "C#" >}} -{{< /clients-example >}} +```cs +bool res30 = db.TOPK().Reserve("top_3_songs", 3, 7, 8, 0.9); +Console.WriteLine(res30); // >>> true + +RedisResult[] res31 = db.TOPK().IncrBy( + "top_3_songs", + new Tuple[] { + new("Starfish Trooper", 3000), + new("Only one more time", 1850), + new("Rock me, Handel", 1325), + new("How will anyone know?", 3890), + new("Average lover", 4098), + new("Road to everywhere", 770) + } +); +Console.WriteLine( + string.Join( + ", ", + string.Join( + ", ", + res31.Select( + r => $"{(r.IsNull ? "Null" : r)}" + ) + ) + ) +); +// >>> Null, Null, Null, Rock me, Handel, Only one more time, Null + +RedisResult[] res32 = db.TOPK().List("top_3_songs"); +Console.WriteLine( + string.Join( + ", ", + string.Join( + ", ", + res32.Select( + r => $"{(r.IsNull ? "Null" : r)}" + ) + ) + ) +); +// >>> Average lover, How will anyone know?, Starfish Trooper + +bool[] res33 = db.TOPK().Query( + "top_3_songs", + "Starfish Trooper", "Road to everywhere" +); +Console.WriteLine(string.Join(", ", res33)); +// >>> true, false +``` + From a13e2b2c899a587011294b4f0e275615d694a72e Mon Sep 17 00:00:00 2001 From: Andy Stark Date: Mon, 28 Jul 2025 12:07:28 +0100 Subject: [PATCH 3/4] DOC-5501 C# trans/pipe examples --- content/develop/clients/dotnet/transpipe.md | 64 +++++++++++++++++++-- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/content/develop/clients/dotnet/transpipe.md b/content/develop/clients/dotnet/transpipe.md index 65e2d5e875..af0ce9d01a 100644 --- a/content/develop/clients/dotnet/transpipe.md +++ b/content/develop/clients/dotnet/transpipe.md @@ -37,8 +37,26 @@ versions of the standard command methods buffered in the pipeline and only execute when you call the `Execute()` method on the pipeline object. -{{< clients-example pipe_trans_tutorial basic_pipe "C#" >}} -{{< /clients-example >}} +```cs +var pipeline = new Pipeline(db); + +for (int i = 0; i < 5; i++) +{ + pipeline.Db.StringSetAsync($"seat:{i}", $"#{i}"); +} +pipeline.Execute(); + +var resp1 = db.StringGet("seat:0"); +Console.WriteLine(resp1); // >>> #0 + +var resp2 = db.StringGet("seat:3"); +Console.WriteLine(resp2); // >>> #3 + +var resp3 = db.StringGet("seat:4"); +Console.WriteLine(resp2); // >>> #4 +``` + ## Execute a transaction @@ -47,8 +65,26 @@ instance of the `Transaction` class, call async command methods on that object, and then call the transaction object's `Execute()` method to execute it. -{{< clients-example pipe_trans_tutorial basic_trans "C#" >}} -{{< /clients-example >}} +```cs +var trans = new Transaction(db); + +trans.Db.StringIncrementAsync("counter:1", 1); +trans.Db.StringIncrementAsync("counter:2", 2); +trans.Db.StringIncrementAsync("counter:3", 3); + +trans.Execute(); + +var resp4 = db.StringGet("counter:1"); +Console.WriteLine(resp4); // >>> 1 + +var resp5 = db.StringGet("counter:2"); +Console.WriteLine(resp5); // >>> 2 + +var resp6 = db.StringGet("counter:3"); +Console.WriteLine(resp6); // >>> 3 +``` + ## Watch keys for changes @@ -77,8 +113,24 @@ For example, the `KeyNotExists` condition aborts the transaction if a specified key exists or is added by another client while the transaction executes: -{{< clients-example pipe_trans_tutorial trans_watch "C#" >}} -{{< /clients-example >}} +```cs +var watchedTrans = new Transaction(db); + +watchedTrans.AddCondition(Condition.KeyNotExists("customer:39182")); + +watchedTrans.Db.HashSetAsync( + "customer:39182", + new HashEntry[]{ + new HashEntry("name", "David"), + new HashEntry("age", "27") + } +); + +bool succeeded = watchedTrans.Execute(); +Console.WriteLine(succeeded); // >>> true +``` + You can also use a `When` condition on certain individual commands to specify that they only execute when a certain condition holds From 7ac10a7d55beff9e99df603d41f0eee2a176d263 Mon Sep 17 00:00:00 2001 From: Andy Stark Date: Mon, 28 Jul 2025 12:14:59 +0100 Subject: [PATCH 4/4] DOC-5501 Jedis prob examples --- content/develop/clients/jedis/prob.md | 185 ++++++++++++++++++++++++-- 1 file changed, 173 insertions(+), 12 deletions(-) diff --git a/content/develop/clients/jedis/prob.md b/content/develop/clients/jedis/prob.md index c426875e93..5e7578ebb5 100644 --- a/content/develop/clients/jedis/prob.md +++ b/content/develop/clients/jedis/prob.md @@ -98,15 +98,50 @@ set's membership with a fixed memory size, regardless of how many items you add. The following example adds some names to a Bloom filter representing a list of users and checks for the presence or absence of users in the list. -{{< clients-example home_prob_dts bloom Java-Sync >}} -{{< /clients-example >}} +```java +List res1 = jedis.bfMAdd( + "recorded_users", + "andy", "cameron", "david", "michelle" +); +System.out.println(res1); // >>> [true, true, true, true] + +boolean res2 = jedis.bfExists("recorded_users", "cameron"); +System.out.println(res2); // >>> true + +boolean res3 = jedis.bfExists("recorded_users", "kaitlyn"); +System.out.println(res3); // >>> false +``` + A Cuckoo filter has similar features to a Bloom filter, but also supports a deletion operation to remove hashes from a set, as shown in the example below. -{{< clients-example home_prob_dts cuckoo Java-Sync >}} -{{< /clients-example >}} +```java +boolean res4 = jedis.cfAdd("other_users", "paolo"); +System.out.println(res4); // >>> true + +boolean res5 = jedis.cfAdd("other_users", "kaitlyn"); +System.out.println(res5); // >>> true + +boolean res6 = jedis.cfAdd("other_users", "rachel"); +System.out.println(res6); // >>> true + +List res7 = jedis.cfMExists( + "other_users", + "paolo", "rachel", "andy" +); +System.out.println(res7); // >>> [true, true, false] + +boolean res8 = jedis.cfDel("other_users", "paolo"); +System.out.println(res8); // >>> true + +boolean res9 = jedis.cfExists("other_users", "paolo"); +System.out.println(res9); // >>> false +``` + Which of these two data types you choose depends on your use case. Bloom filters are generally faster than Cuckoo filters when adding new items, @@ -126,8 +161,30 @@ You can also merge two or more HyperLogLogs to find the cardinality of the [union](https://en.wikipedia.org/wiki/Union_(set_theory)) of the sets they represent. -{{< clients-example home_prob_dts hyperloglog Java-Sync >}} -{{< /clients-example >}} +```java +long res10 = jedis.pfadd("group:1", "andy", "cameron", "david"); +System.out.println(res10); // >>> 1 + +long res11 = jedis.pfcount("group:1"); +System.out.println(res11); // >>> 3 + +long res12 = jedis.pfadd( + "group:2", + "kaitlyn", "michelle", "paolo", "rachel" +); +System.out.println(res12); // >>> 1 + +long res13 = jedis.pfcount("group:2"); +System.out.println(res13); // >>> 4 + +String res14 = jedis.pfmerge("both_groups", "group:1", "group:2"); +System.out.println(res14); // >>> OK + +long res15 = jedis.pfcount("both_groups"); +System.out.println(res15); // >>> 7 +``` + The main benefit that HyperLogLogs offer is their very low memory usage. They can count up to 2^64 items with less than @@ -165,8 +222,44 @@ stay within 0.1% of the true value and have a 0.05% probability of going outside this limit. The example below shows how to create a Count-min sketch object, add data to it, and then query it. -{{< clients-example home_prob_dts cms Java-Sync >}} -{{< /clients-example >}} +```java +// Specify that you want to keep the counts within 0.01 +// (1%) of the true value with a 0.005 (0.5%) chance +// of going outside this limit. +String res16 = jedis.cmsInitByProb("items_sold", 0.01, 0.005); +System.out.println(res16); // >>> OK + +Map firstItemIncrements = new HashMap<>(); +firstItemIncrements.put("bread", 300L); +firstItemIncrements.put("tea", 200L); +firstItemIncrements.put("coffee", 200L); +firstItemIncrements.put("beer", 100L); + +List res17 = jedis.cmsIncrBy("items_sold", + firstItemIncrements +); +res17.sort(null); +System.out.println(); // >>> [100, 200, 200, 300] + +Map secondItemIncrements = new HashMap<>(); +secondItemIncrements.put("bread", 100L); +secondItemIncrements.put("coffee", 150L); + +List res18 = jedis.cmsIncrBy("items_sold", + secondItemIncrements +); +res18.sort(null); +System.out.println(res18); // >>> [350, 400] + +List res19 = jedis.cmsQuery( + "items_sold", + "bread", "tea", "coffee", "beer" +); +res19.sort(null); +System.out.println(res19); // >>> [100, 200, 350, 400] +``` + The advantage of using a CMS over keeping an exact count with a [sorted set]({{< relref "/develop/data-types/sorted-sets" >}}) @@ -197,8 +290,48 @@ maximum values, the quantile of 0.75, and the shows how to merge two or more t-digest objects to query the combined data set. -{{< clients-example home_prob_dts tdigest Java-Sync >}} -{{< /clients-example >}} +```java +String res20 = jedis.tdigestCreate("male_heights"); +System.out.println(res20); // >>> OK + +String res21 = jedis.tdigestAdd("male_heights", + 175.5, 181, 160.8, 152, 177, 196, 164); +System.out.println(res21); // >>> OK + +double res22 = jedis.tdigestMin("male_heights"); +System.out.println(res22); // >>> 152.0 + +double res23 = jedis.tdigestMax("male_heights"); +System.out.println(res23); // >>> 196.0 + +List res24 = jedis.tdigestQuantile("male_heights", 0.75); +System.out.println(res24); // >>> [181.0] + +// Note that the CDF value for 181 is not exactly 0.75. +// Both values are estimates. +List res25 = jedis.tdigestCDF("male_heights", 181); +System.out.println(res25); // >>> [0.7857142857142857] + +String res26 = jedis.tdigestCreate("female_heights"); +System.out.println(res26); // >>> OK + +String res27 = jedis.tdigestAdd("female_heights", + 155.5, 161, 168.5, 170, 157.5, 163, 171); +System.out.println(res27); // >>> OK + +List res28 = jedis.tdigestQuantile("female_heights", 0.75); +System.out.println(res28); // >>> [170.0] + +String res29 = jedis.tdigestMerge( + "all_heights", + "male_heights", "female_heights" +); +System.out.println(res29); // >>> OK +List res30 = jedis.tdigestQuantile("all_heights", 0.75); +System.out.println(res30); // >>> [175.5] +``` + A t-digest object also supports several other related commands, such as querying by rank. See the @@ -219,5 +352,33 @@ the `topkReserve()` method). It also shows how to list the top *k* items and query whether or not a given item is in the list. -{{< clients-example home_prob_dts topk Java-Sync >}} -{{< /clients-example >}} +```java +String res31 = jedis.topkReserve("top_3_songs", 3L, 2000L, 7L, 0.925D); +System.out.println(res31); // >>> OK + +Map songIncrements = new HashMap<>(); +songIncrements.put("Starfish Trooper", 3000L); +songIncrements.put("Only one more time", 1850L); +songIncrements.put("Rock me, Handel", 1325L); +songIncrements.put("How will anyone know?", 3890L); +songIncrements.put("Average lover", 4098L); +songIncrements.put("Road to everywhere", 770L); + +List res32 = jedis.topkIncrBy("top_3_songs", + songIncrements +); +System.out.println(res32); +// >>> [null, null, null, null, null, Rock me, Handel] + +List res33 = jedis.topkList("top_3_songs"); +System.out.println(res33); +// >>> [Average lover, How will anyone know?, Starfish Trooper] + +List res34 = jedis.topkQuery("top_3_songs", + "Starfish Trooper", "Road to everywhere" +); +System.out.println(res34); +// >>> [true, false] +``` +