
# scan指定match参数，数据中确实存在匹配的key，为什么返回的是空
#### 问题描述
如下图所示，数据库中存在key为test的数据，用scan match的方式却没有返回这个数据。
```
139.9.177.148：6379> scan 1 match tes*
1) "21"
2) (empty list or set)
139.9.177.148：6379> get test
"abc"
139.9.177.148：6379>scan 0 match tes*
1) "21"
2) (empty list or set)
139.9.177.148：6379>
```
#### 问题分析
MATCH选项让命令只返回和给定模式相匹配的元素， 对元素的模式匹配工作是在命令从数据集中取出元素之后， 向客户端返回元素之前的这段时间内进行的， 如果取出的元素都和模式不匹配，则不会返回任何元素。
#### 解决方案
多次scan，以返回的游标值是否为0作为全遍历结束的标记，每次scan时使用上次scan返回的游标值。
 #### 相关知识
- **SCAN命令的基本用法**
  **SCAN cursor \[MATCH pattern\] \[COUNT count\]**
  SCAN命令是一个基于游标的迭代器（cursor based iterator）。SCAN命令每次被调用之后， 都会向用户返回一个新的游标， 用户在下次迭代时需要使用这个新游标作为 SCAN命令的游标参数， 以此来延续之前的迭代过程。
  当SCAN命令的游标参数被设置为0时， 服务器将开始一次新的迭代， 而当服务器向用户返回值为0的游标时， 表示迭代已结束。
  ```
  redis 127.0.0.1:6379> scan 0 
  1) "17" 
  2) 1) "key:12"
     2) "key:8"
     3) "key:4"
     4) "key:14"
     5) "key:16"
     6) "key:17"
     7) "key:15"
     8) "key:10"
     9) "key:3"
     10) "key:7"
     11) "key:1"
  redis 127.0.0.1:6379> scan 17 
  1) "0"
  2) 1) "key:5" 
     2) "key:18"
     3) "key:0"
     4) "key:2"
     5) "key:19"
     6) "key:13"
     7) "key:6"
     8) "key:9"
     9) "key:11"
  ```
  在上面这个例子中， 第一次迭代使用0作为游标， 表示开始一次新的迭代。
  第二次迭代使用的是第一次迭代时返回的游标， 即命令回复第一个元素的值 ：17 。
  从上面的示例可以看到， SCAN命令的回复是一个包含两个元素的数组， 第一个数组元素是用于进行下一次迭代的新游标， 而第二个数组元素则是一个数组， 这个数组中包含了所有被迭代的元素。
  在第二次调用SCAN命令时， 命令返回了游标0 ， 这表示迭代已经结束， 整个数据集（collection）已经被完整遍历过了。
  以0作为游标开始一次新的迭代， 一直调用SCAN命令， 直到命令返回游标0， 我们称这个过程为一次完整遍历（full iteration）。
  
- **COUNT选项**
  虽然增量式迭代命令不保证每次迭代所返回的元素数量， 但我们可以使用COUNT选项， 对命令的行为进行一定程度上的调整。
  基本上，COUNT选项的作用就是让用户告知迭代命令， 在每次迭代中应该从数据集里返回多少元素。 COUNT参数的默认值为10。
  并非每次迭代都要使用相同的COUNT值。
  用户可以在每次迭代中按自己的需要随意改变COUNT值， 只要记得将上次迭代返回的游标用到下次迭代里面。
  
- **MATCH选项**
  MATCH选项让命令只返回和给定模式相匹配的元素，以下是一个使用MATCH选项进行迭代的示例。
  ```
  redis 127.0.0.1:6379> mset foo a foobar b feelsgood c bar d (integer) 4
  redis 127.0.0.1:6379> scan 0 match f*
   1) "0"
   2) 1) "foo"
      2) "feelsgood"
      3) "foobar"
  ```
  需要注意的是， 对元素的模式匹配工作是在命令从数据集中取出元素之后， 向客户端返回元素之前的这段时间内进行的， 所以如果被迭代的数据集中只有少量元素和模式相匹配， 那么迭代命令或许会在多次执行中都不返回任何元素。
  以下是这种情况的一个例子。
  ```
  redis 127.0.0.1:6379> scan 0 MATCH *11*
   1) "288"
   2) 1) "key:911"
  redis 127.0.0.1:6379> scan 288 MATCH *11*
   1) "224"
   2) (empty list or set)
  redis 127.0.0.1:6379> scan 176 MATCH *11* COUNT 1000
   1) "0"
   2)  1) "key:611"
       2) "key:711" 
       3) "key:118" 
       4) "key:117"
       5) "key:311"
       6) "key:112" 
       7) "key:111" 
       8) "key:110" 
       9) "key:113"
       10) "key:211"
       11) "key:411"
       12) "key:115"
       13) "key:116"
       14) "key:114"
       15) "key:119"
       16) "key:811"
       17) "key:511"
       18) "key:11"
  ```
  以上的大部分迭代都不返回任何元素。 在最后一次迭代， 我们通过将COUNT选项的参数设置为1000 ， 强制命令为本次迭代扫描更多元素， 从而使得命令返回的元素也变多了。
  
 
