You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redis SCAN命令模式匹配NOT运算符及匹配失效问题咨询

Redis SCAN Pattern Matching: Why Your Patterns Behave Differently & How to Exclude Route Keys

Hey there! Let's unpack your Redis SCAN questions and get to the bottom of what's happening here.

First: Why Your Current Patterns Work (or Don't)

First off, it's critical to remember that Redis' SCAN MATCH parameter uses glob-style pattern matching, not full regular expressions. That's the root of why your two patterns behave so differently:

1. SCAN 0 MATCH trip:*[^:routes] (Seems to Work)

This pattern isn't actually excluding keys ending with :routes—it's just a happy coincidence given your current key set. Here's what it really does:

  • trip:* matches any key starting with trip:
  • [^:routes] matches a single character that is NOT one of :, r, o, u, t, e, or s

Since your main trip key is trip:1734 (ends with 4, which isn't in that excluded set) and your route key is trip:1734:routes (ends with s, which is in the excluded set), this pattern filters out the route key. But this is fragile: if you had a valid trip key ending with e or r, it would get incorrectly filtered out. This pattern isn't reliable for your actual goal.

2. SCAN 0 MATCH trip:*[^:*] (Doesn't Work)

This pattern tries to exclude keys with :* at the end, but glob logic gets in the way:

  • [^:*] matches a single character that is NOT : or *

Both your keys trip:1734 (ends with 4) and trip:1734:routes (ends with s) pass this check—neither ends with : or *—so both get matched. That's why it fails to exclude the route key.

The Real Problem: Redis SCAN Has No Built-in NOT Operator

Unfortunately, Redis' glob pattern matching for SCAN doesn't include a proper NOT operator to exclude entire suffixes or patterns. The [^...] syntax only works for single characters, not multi-character strings.

How to Properly Get Trip Keys Without Routes

You have a few reliable options to achieve your goal:

Option 1: Client-Side Filtering

Scan all trip:* keys, then filter out the ones ending with :routes in your application code. For example, in Python:

import redis
r = redis.Redis()

cursor = 0
while True:
    cursor, keys = r.scan(cursor, match='trip:*')
    for key in keys:
        if not key.endswith(b':routes'):  # Adjust based on your language's string handling
            print(key)
    if cursor == 0:
        break

This is straightforward and works regardless of your trip key naming format.

Option 2: Use a More Precise Glob Pattern (If Possible)

If your main trip keys follow a strict format (like trip:[0-9]+), you can match directly against that pattern:

SCAN 0 MATCH trip:[0-9]*

This works only if all non-route trip keys fit this format—if you have keys like trip:nyc-central, this won't help.

Option 3: Maintain a Dedicated Set of Main Trip Keys

For better performance (especially with large key spaces), create a Redis Set that tracks all your main trip keys. When you create a trip key like trip:1734, add it to the set:

SADD trip:main_keys trip:1734

Then, to get all main trip keys, just scan or fetch from this set:

SSCAN 0 MATCH *  # Or SMEMBERS if the set is small

This avoids scanning all trip:* keys entirely and is the most efficient approach for large-scale use.

Key Takeaways

  • Redis SCAN uses glob patterns, not regex—forget about regex-style negative lookaheads or full string negation.
  • The [^...] syntax only excludes single characters, not multi-character suffixes.
  • To exclude specific key patterns, use client-side filtering or maintain a dedicated index set for your main keys.

内容的提问来源于stack exchange,提问作者cybercoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:42:07