مجموعات Redis المرتبة (الجزء 2)

يغطي هذا الدرس ميزات المجموعات المرتبة المتقدمة مثل استعلامات نطاق الدرجة وعمليات المجموعات.

ZRANGEBYSCORE: الاستعلام حسب نطاق الدرجة

ZRANGEBYSCORE يسترجع العناصر بناءً على نطاق درجة.

الاستخدام الأساسي

REDIS
ZADD leaderboard 100 "player1" 150 "player2" 200 "player3" 250 "player4" 300 "player5"

# الحصول على العناصر بدرجات بين 150 و 250
ZRANGEBYSCORE leaderboard 150 250
1) "player2"
2) "player3"
3) "player4"

# الحصول على العناصر مع الدرجات
ZRANGEBYSCORE leaderboard 150 250 WITHSCORES
1) "player2"
2) "150"
3) "player3"
4) "200"
5) "player4"
6) "250"

استخدام -inf و +inf

REDIS
# الحصول على العناصر بدرجة <= 200
ZRANGEBYSCORE leaderboard -inf 200
1) "player1"
2) "player2"
3) "player3"

# الحصول على العناصر بدرجة >= 200
ZRANGEBYSCORE leaderboard 200 +inf
1) "player3"
2) "player4"
3) "player5"

# الحصول على جميع العناصر
ZRANGEBYSCORE leaderboard -inf +inf

الفترات المفتوحة والمغلقة

REDIS
# الافتراضي هو الفترة المغلقة [150, 250]
ZRANGEBYSCORE leaderboard 150 250

# الفترة المفتوحة (150, 250) — تستبعد 150 و 250
ZRANGEBYSCORE leaderboard (150 (250

# نصف مفتوحة [150, 250)
ZRANGEBYSCORE leaderboard 150 (250

# نصف مفتوحة (150, 250]
ZRANGEBYSCORE leaderboard (150 250
💡 الصيغة: استخدم الأقواس ( للإشارة إلى فترة مفتوحة (استبعادية)، بدون أقواس لفترة مغلقة (شاملة).

LIMIT الترقيم

REDIS
# الحصول على العناصر بدرجات 100-300، بدءًا من الفهرس 1، خذ 2
ZRANGEBYSCORE leaderboard 100 300 LIMIT 1 2
1) "player2"
2) "player3"

ZREVRANGEBYSCORE: الاستعلام حسب نطاق الدرجة (من الأعلى إلى الأقل)

REDIS
# الحصول على العناصر بدرجات 150-250، من الأعلى إلى الأقل
ZREVRANGEBYSCORE leaderboard 250 150 WITHSCORES
1) "player4"
2) "250"
3) "player3"
4) "200"
5) "player2"
6) "150"
⚠️ ملاحظة: نطاق الدرجة في ZREVRANGEBYSCORE يذهب من الأعلى إلى الأقل (250 150)، وليس من الأقل إلى الأعلى.

ZRANGEBYLEX: الاستعلام حسب الترتيب المعجمي

عندما تكون جميع العناصر لها نفس الدرجة، يمكنك الاستعلام حسب الترتيب المعجمي (الأبجدي).

الاستخدام الأساسي

REDIS
# جميع العناصر لها درجة 0
ZADD myzset 0 "apple" 0 "banana" 0 "cherry" 0 "date"

# الحصول على جميع العناصر بالترتيب المعجمي
ZRANGEBYLEX myzset - +
1) "apple"
2) "banana"
3) "cherry"
4) "date"

# الحصول على العناصر في النطاق المعجمي [banana, cherry]
ZRANGEBYLEX myzset [banana [cherry
1) "banana"
2) "cherry"

# الحصول على العناصر التي تبدأ بـ "b"
ZRANGEBYLEX myzset [b (c
1) "banana"
💡 حالة الاستخدام: ZRANGEBYLEX مثالي لتنفيذ الإكمال التلقائي وعمليات البحث في القاموس.

ZREMRANGEBYRANK: الإزالة حسب نطاق الترتيب

REDIS
ZADD leaderboard 100 "p1" 150 "p2" 200 "p3" 250 "p4" 300 "p5"

# إزالة العناصر ذات الترتيب 0 إلى 1 (أدنى درجتين)
ZREMRANGEBYRANK leaderboard 0 1
(integer) 2

ZRANGE leaderboard 0 -1
1) "p3"
2) "p4"
3) "p5"

ZREMRANGEBYSCORE: الإزالة حسب نطاق الدرجة

REDIS
ZADD leaderboard 100 "p1" 150 "p2" 200 "p3" 250 "p4" 300 "p5"

# إزالة العناصر بدرجات بين 100 و 200
ZREMRANGEBYSCORE leaderboard 100 200
(integer) 3

ZRANGE leaderboard 0 -1 WITHSCORES
1) "p4"
2) "250"
3) "p5"
4) "300"

حالة الاستخدام: تنظيف البيانات منتهية الصلاحية

REDIS
# قائمة انتظار مؤجلة (الدرجة هي طابع زمني)
ZADD delay:queue 1719129600 "task:1"
ZADD delay:queue 1719133200 "task:2"

# إزالة المهام المكتملة (طابع زمني أقل من الوقت الحالي)
ZREMRANGEBYSCORE delay:queue -inf 1719129600

ZREMRANGEBYLEX: الإزالة حسب النطاق المعجمي

REDIS
ZADD myzset 0 "apple" 0 "banana" 0 "cherry" 0 "date"

# إزالة العناصر في النطاق المعجمي [banana, cherry]
ZREMRANGEBYLEX myzset [banana [cherry
(integer) 2

ZRANGE myzset 0 -1
1) "apple"
2) "date"

عمليات المجموعات المرتبة

ZUNIONSTORE: الاتحاد

REDIS
# إنشاء مجموعتين مرتبتين
ZADD zset1 1 "a" 2 "b" 3 "c"
ZADD zset2 4 "b" 5 "c" 6 "d"

# حساب الاتحاد (الافتراضي: جمع الدرجات)
ZUNIONSTORE result 2 zset1 zset2
(integer) 4

ZRANGE result 0 -1 WITHSCORES
1) "a"
2) "1"
3) "d"
4) "6"
5) "b"
6) "6"   # 2 + 4
7) "c"
8) "8"   # 3 + 5

ZUNIONSTORE مع الأوزان

REDIS
# تعيين الأوزان
ZUNIONSTORE result 2 zset1 zset2 WEIGHTS 2 3
# درجات zset1 مضروبة في 2، درجات zset2 مضروبة في 3

ZRANGE result 0 -1 WITHSCORES
1) "a"
2) "2"   # 1 * 2
3) "d"
4) "18"  # 6 * 3
5) "b"
6) "16"  # 2*2 + 4*3
7) "c"
8) "21"  # 3*2 + 5*3

وظائف التجميع ZUNIONSTORE

REDIS
# استخدام تجميع MIN (أخذ أقل درجة)
ZUNIONSTORE result 2 zset1 zset2 AGGREGATE MIN

# استخدام تجميع MAX (أخذ أعلى درجة)
ZUNIONSTORE result 2 zset1 zset2 AGGREGATE MAX

# استخدام تجميع SUM (الجمع، الافتراضي)
ZUNIONSTORE result 2 zset1 zset2 AGGREGATE SUM

ZINTERSTORE: التقاطع

REDIS
ZADD zset1 1 "a" 2 "b" 3 "c"
ZADD zset2 4 "b" 5 "c" 6 "d"

# حساب التقاطع
ZINTERSTORE result 2 zset1 zset2
(integer) 2

ZRANGE result 0 -1 WITHSCORES
1) "b"
2) "6"   # 2 + 4
3) "c"
4) "8"   # 3 + 5

ZDIFFSTORE: الفرق (Redis 6.2+)

REDIS
ZADD zset1 1 "a" 2 "b" 3 "c"
ZADD zset2 4 "b" 5 "c" 6 "d"

# حساب الفرق
ZDIFFSTORE result 2 zset1 zset2
(integer) 1

ZRANGE result 0 -1 WITHSCORES
1) "a"
2) "1"

ZMSCORE: الحصول على درجات دفعات (Redis 6.2+)

REDIS
ZADD leaderboard 100 "player1" 200 "player2" 300 "player3"

ZMSCORE leaderboard "player1" "player2" "player4"
1) "100"
2) "200"
3) (nil)  # player4 غير موجود

ZPOPMAX و ZPOPMIN: إخراج العناصر ذات أعلى/أقل درجة

ZPOPMAX: إخراج العنصر ذي أعلى درجة

REDIS
ZADD leaderboard 100 "p1" 200 "p2" 300 "p3"

# إخراج العنصر ذي أعلى درجة
ZPOPMAX leaderboard
1) "p3"
2) "300"

# إخراج عنصرين ذوي أعلى درجة
ZPOPMAX leaderboard 2
1) "p2"
2) "200"
3) "p1"
4) "100"

ZPOPMIN: إخراج العنصر ذي أقل درجة

REDIS
ZADD leaderboard 100 "p1" 200 "p2" 300 "p3"

ZPOPMIN leaderboard
1) "p1"
2) "100"

BZPOPMAX و BZPOPMIN: إخراج محظور

REDIS
# إذا كانت المجموعة المرتبة فارغة، انتظر حتى 10 ثوانٍ
BZPOPMAX leaderboard 10

# الاستماع على مجموعات مرتبة متعددة
BZPOPMAX zset1 zset2 zset3 10
💡 حالة الاستخدام: BZPOPMAX/BZPOPMIN يمكن استخدامها لتنفيذ قوائم انتظار ذات أولوية.

تطبيقات المجموعات المرتبة المتقدمة

حالة الاستخدام 1: تحديد معدل النافذة المنزلقة

REDIS
# تسجيل طوابع زمنية لطلبات المستخدم
ZADD ratelimit:user:1 1719129600 "req1"
ZADD ratelimit:user:1 1719129605 "req2"
ZADD ratelimit:user:1 1719129610 "req3"

# عد الطلبات في آخر 60 ثانية
ZCOUNT ratelimit:user:1 1719129540 1719129600

# تنظيف الطلبات الأقدم من 60 ثانية
ZREMRANGEBYSCORE ratelimit:user:1 -inf 1719129540

حالة الاستخدام 2: الإكمال التلقائي

REDIS
# جميع الكلمات بدرجة 0
ZADD autocomplete 0 "apple" 0 "application" 0 "appetite" 0 "banana"

# استعلام الكلمات التي تبدأ بـ "app"
ZRANGEBYLEX autocomplete [app [app\xff
1) "apple"
2) "application"
3) "appetite"

حالة الاستخدام 3: خط زمني

REDIS
# الخط الزمني للمستخدم (الدرجة هي طابع زمني)
ZADD timeline:user:1 1719129600 "post:1"
ZADD timeline:user:1 1719129605 "post:2"
ZADD timeline:user:1 1719129610 "post:3"

# الحصول على أحدث 10 منشورات
ZREVRANGE timeline:user:1 0 9

# الحصول على المنشورات ضمن نطاق زمني
ZRANGEBYSCORE timeline:user:1 1719129600 1719129610

حالة الاستخدام 4: ترتيب متعدد الأبعاد

REDIS
# ترتيب مبيعات المنتجات
ZADD sales:rank 1000 "product:1"
ZADD sales:rank 2000 "product:2"

# ترتيب تقييم المنتجات
ZADD rating:rank 4.5 "product:1"
ZADD rating:rank 4.8 "product:2"

# ترتيب مدمج (وزن المبيعات 0.6، وزن التقييم 0.4)
ZUNIONSTORE combined:rank 2 sales:rank rating:rank WEIGHTS 0.6 0.4

❓ أسئلة شائعة

س ما الفرق بين ZRANGEBYSCORE و ZRANGE؟
ج ZRANGE يستعلم حسب نطاق الترتيب؛ ZRANGEBYSCORE يستعلم حسب نطاق الدرجة。
س كيف أحصل على أفضل N عنصر حسب الدرجة؟
ج استخدم ZREVRANGE key 0 N-1 WITHSCORES
س كيف تعمل الأوزان في ZUNIONSTORE؟
ج الأوزان هي مضاعفات. WEIGHTS 2 3 تعني ضرب درجات المجموعة الأولى في 2 والمجموعة الثانية في 3。
س هل يتطلب ZRANGEBYLEX أن تكون جميع العناصر بنفس الدرجة؟
ج نعم. ZRANGEBYLEX يفترض أن جميع العناصر لها نفس الدرجة ويُرتبها معجميًا。
س كيف أنفذ قائمة انتظار ذات أولوية؟
ج استخدم ZADD لإضافة مهام (الدرجة = الأولوية)، و ZPOPMIN لإخراج المهمة ذات الأولوية الأعلى。

📖 ملخص

📝 تمارين

  1. استعلام نطاق درجة: استخدم ZRANGEBYSCORE لاستعلام العناصر في نطاقات درجات مختلفة
  2. حذف النطاق: استخدم ZREMRANGEBYSCORE لتنظيف البيانات منتهية الصلاحية
  3. عمليات المجموعات: استخدم ZUNIONSTORE لدمج لوحات متصدرين متعددة بأوزان مختلفة
  4. نافذة منزلقة: استخدم مجموعة مرتبة لتنفيذ تحديد معدل النافذة المنزلقة

الدرس التالي

في الدرس التالي، سنتعلم HyperLogLog في Redis، والذي يغطي تقدير العددية.

100%