{"id":28255,"date":"2022-12-27T11:50:20","date_gmt":"2022-12-27T01:50:20","guid":{"rendered":"https:\/\/database.guide\/?p=28255"},"modified":"2022-12-28T12:16:45","modified_gmt":"2022-12-28T02:16:45","slug":"redis-zdiff-command-explained","status":"publish","type":"post","link":"https:\/\/database.guide\/redis-zdiff-command-explained\/","title":{"rendered":"Redis ZDIFF Command Explained"},"content":{"rendered":"\n<p>In Redis, the <code>ZDIFF<\/code> command returns the difference between the first and all successive input sorted sets.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>There&#8217;s also a <code><a href=\"https:\/\/database.guide\/redis-zdiffstore-command-explained\/\" data-type=\"post\" data-id=\"28276\">ZDIFFSTORE<\/a><\/code> command that stores the result in a key.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Syntax<\/h2>\n\n\n\n<p>The syntax for <code>ZDIFF<\/code> goes like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ZDIFF numkeys key &#91;key ...] &#91;WITHSCORES]<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Example<\/h2>\n\n\n\n<p>Suppose we create two sorted sets, like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ZADD cats 1 meow 2 fluffy 3 scratch<\/code><\/pre>\n\n\n\n<p>And:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ZADD dogs 1 bark 2 woof<\/code><\/pre>\n\n\n\n<p>We can use the <code>ZDIFF<\/code> command against those two sorted sets like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ZDIFF 2 cats dogs<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">1) \"meow\"\n2) \"fluffy\"\n3) \"scratch\"<\/pre>\n\n\n\n<p>That returns all the elements in the first set that aren&#8217;t in the second set. By this, I mean all elements whose values aren&#8217;t in the second set.<\/p>\n\n\n\n<p>Let&#8217;s add an element to the <code>dogs<\/code> set:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ZADD dogs 3 fluffy<\/code><\/pre>\n\n\n\n<p>Now let&#8217;s run <code>ZDIFF<\/code> again:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ZDIFF 2 cats dogs<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">1) \"meow\"\n2) \"scratch\"<\/pre>\n\n\n\n<p>This time only two elements are returned. That&#8217;s because <code>fluffy<\/code> appears in both sorted sets and <code>ZDIFF<\/code> only returns the difference between the first sorted set and all subsequent sorted sets.<\/p>\n\n\n\n<p>The <em><code>numkeys<\/code><\/em> value of <code>2<\/code> in the above examples means that I&#8217;m providing two sets.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">More Sorted Sets<\/h2>\n\n\n\n<p>The <code>ZDIFF<\/code> command allows us to include as many sorted sets as we want in our list. They are all compared to the first one and any difference between the first and subsequent sets are returned.<\/p>\n\n\n\n<p>Let&#8217;s create another sorted set:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ZADD birds 1 tweet 2 scratch<\/code><\/pre>\n\n\n\n<p>Now let&#8217;s run <code>ZDIFF<\/code> against all three sets:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ZDIFF 3 cats dogs birds<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">1) \"meow\"<\/pre>\n\n\n\n<p>This time only one element is returned. That&#8217;s because the other elements from the <code>cats<\/code> set contain values that are also present in at least one of the other sorted sets. That is, the <code>dogs<\/code> set contains <code>fluffy<\/code> and the <code>birds<\/code> set contains <code>scratch<\/code>, both of which are in the <code>cats<\/code> set.<\/p>\n\n\n\n<p>Note that the <em><code>numkeys<\/code><\/em> argument is now <code>3<\/code>, which reflects the number of sorted sets I&#8217;m providing.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The <code>WITHSCORES<\/code> Argument<\/h2>\n\n\n\n<p>The <code>WITHSCORES<\/code> argument can be used to output the scores of each element returned:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ZDIFF 2 cats dogs WITHSCORES<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">1) \"meow\"\n2) \"1\"\n3) \"scratch\"\n4) \"3\"<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Non-Existent Keys<\/h2>\n\n\n\n<p>Keys that don&#8217;t exist are treated as empty sets:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ZDIFF 2 oops1 oops2<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(empty array)<\/pre>\n\n\n\n<p>Here we got an empty array because none of the keys exist.<\/p>\n\n\n\n<p>Here&#8217;s what happens when the first key exists, but none of the others do:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ZDIFF 3 cats oops1 oops2<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">1) \"meow\"\n2) \"fluffy\"\n3) \"scratch\"<\/pre>\n\n\n\n<p>All elements from the first set are returned because none of them are present in any of the other (empty) sets.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Using the Wrong <code><em>numkeys<\/em><\/code> Argument<\/h2>\n\n\n\n<p>Here&#8217;s what happens when we use the wrong value for the <code><em>numkeys<\/em><\/code> argument:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ZDIFF 3 cats dogs<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(error) ERR syntax error<\/pre>\n\n\n\n<p>In this case I specified that there would be three sorted sets to compare, but I only provided two.<\/p>\n\n\n\n<p>The same error applies when it&#8217;s the other way around (i.e. I specify <code>2<\/code> but provide three keys):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ZDIFF 2 cats dogs birds<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(error) ERR syntax error<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Passing a Key of the Wrong Type<\/h2>\n\n\n\n<p>Here&#8217;s what happens when we pass a key that contains a different type (i.e. it&#8217;s not a sorted set):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ZDIFF 2 cats country<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(error) WRONGTYPE Operation against a key holding the wrong kind of value<\/pre>\n\n\n\n<p>Here the <code>country<\/code> key contains a string.<\/p>\n\n\n\n<p>However, the command does work on non-sorted sets:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ZDIFF 2 countries cats<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">1) \"Australia\"\n2) \"New Zealand\"<\/pre>\n\n\n\n<p>In this case the <code>countries<\/code> key contains a (non-sorted) set.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Redis, the ZDIFF command returns the difference between the first and all successive input sorted sets.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[153],"tags":[154,20],"class_list":["post-28255","post","type-post","status-publish","format-standard","hentry","category-redis","tag-commands","tag-what-is"],"_links":{"self":[{"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/posts\/28255","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/comments?post=28255"}],"version-history":[{"count":5,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/posts\/28255\/revisions"}],"predecessor-version":[{"id":28303,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/posts\/28255\/revisions\/28303"}],"wp:attachment":[{"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/media?parent=28255"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/categories?post=28255"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/tags?post=28255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}