سؤال

لنقول إن لدي حوالي 1،000،000 مستخدم. أريد أن أعرف أي موقف يوجد فيه أي مستخدم معين ، وأي المستخدمين حوله. يمكن للمستخدم الحصول على إنجاز جديد في أي وقت ، وإذا كان بإمكانه رؤية تحديثه الدائم ، فسيكون ذلك رائعًا.

بصراحة ، كل طريقة أفكر في القيام بذلك ستكون باهظة الثمن في الوقت المناسب و/أو الذاكرة. أفكار؟ إن أقرب فكرتي حتى الآن هي طلب المستخدمين في وضع عدم الاتصال وإنشاء دلاء مئوية ، لكن هذا لا يمكن أن يظهر للمستخدم موقعه الدقيق.

بعض التعليمات البرمجية إذا كان ذلك يساعدك في Django:

class Alias(models.Model) :
    awards = models.ManyToManyField('Award', through='Achiever')

    @property
    def points(self) :
        p = cache.get('alias_points_' + str(self.id))
        if p is not None : return p

        points = 0
        for a in self.achiever_set.all() :
            points += a.award.points * a.count

        cache.set('alias_points_' + str(self.id), points, 60 * 60) # 1 hour
        return points

class Award(MyBaseModel):
    owner_points = models.IntegerField(help_text="A non-normalized point value. Very subjective but try to be consistent. Should be proporional. 2x points = 2x effort (or skill)")
    true_points = models.FloatField(help_text="The true value of this award. Recalculated with a cron job. Based on number of people who won it", editable=False, null=True)

    @property
    def points(self) :
        if self.true_points :
            # blend true_points into real points over 30 days
            age = datetime.now() - self.created
            blend_days = 30
            if age > timedelta(days=blend_days) :
                age = timedelta(days=blend_days)
            num_days = 1.0 * age.days / blend_days
            r = self.true_points * num_days + self.owner_points * (1 - num_days)
            return int(r * 10) / 10.0

        else :
            return self.owner_points


class Achiever(MyBaseModel):
    award = models.ForeignKey(Award)
    alias = models.ForeignKey(Alias)
    count = models.IntegerField(default=1)
هل كانت مفيدة؟

المحلول

أعتقد أن Counterstrike يحل هذا من خلال مطالبة المستخدمين بتلبية الحد الأدنى من الحد الأدنى لتصبح المرتبة-تحتاج فقط إلى فرز أفضل 10 ٪ أو أي شيء آخر بدقة.

إذا كنت ترغب في فرز الجميع ، ففكر في أنك لا تحتاج إلى فرزهم تمامًا: فرزها إلى شخصين مهمين. مع 1 مليون مستخدم ، يمكنك تحديث لوحة المتصدرين لأفضل 100 مستخدم في الوقت الفعلي ، وهو 1000 مستخدم التالي إلى أقرب 10 ، ثم الجماهير إلى أقرب 1 ٪ أو 10 ٪. لن تقفز من المكان 500000 إلى مكان 99 في جولة واحدة.

لا معنى لها للحصول على سياق المستخدم العشرة أعلاه وتحت المكان 500000-سيكون ترتيب الجماهير متوترة بشكل لا يصدق من الجولة إلى الجولة بسبب التوزيع الأسي.

تحرير: ألق نظرة على حتى المتصدرين. اذهب الآن إلى صفحة 500 من أصل 2500 (حوالي 20 النسبة المئوية). هل هناك أي نقطة لإخبار الأشخاص الذين يعانون من "157" أن 10 أشخاص على جانبيهم لديهم أيضًا مندوب "157"؟ ستقفز 20 مكانًا في كلتا الحالتين إذا ارتفع مندوبك أو أسفل نقطة. أكثر تطرفًا ، هو أن 1056 صفحة السفلية الآن (من 2538) ، أو 42 ٪ من المستخدمين ، مرتبطة بـ REP 1. تحصل على نقطة أخرى ، وقفزت إلى أعلى 1055 صفحة. وهو ما يقرب من 37000 زيادة في المرتبة. قد يكون من الرائع إخبارهم "يمكنك التغلب على 37 ألف شخص إذا حصلت على نقطة أخرى!" ولكن هل يهم كم عدد الأرقام المهمة التي يحملها رقم 37K؟

لا توجد قيمة في معرفة أقرانك على سلم حتى تكون بالفعل في الأعلى ، لأنه في أي مكان سوى الجزء العلوي ، هناك عدد هائل منهم.

نصائح أخرى

مليون ليس كثيرًا ، سأحاول ذلك بالطريقة السهلة أولاً. إذا كانت خاصية Points هي الشيء الذي تقوم بفرزه على أنه يجب أن يكون عمود قاعدة بيانات. ثم يمكنك فقط القيام بعدد من النقاط أكبر من الشخص المعني للحصول على المرتبة. للحصول على أشخاص آخرين بالقرب من شخص معني ، تقوم بإجراء استعلام عن الأشخاص الذين لديهم نقاط أعلى وفرز الحد الصاعد إلى عدد الأشخاص الذين تريدهم.

سوف يكون الشيء الصعب حساب النقاط في الحفظ. تحتاج إلى استخدام الوقت الحالي كمضاعف إضافي. تحتاج نقطة واحدة الآن إلى أن تتحول إلى رقم أقل من نقطة واحدة 5 أيام من الآن. إذا حصل المستخدمون بشكل متكرر على نقاط ، فستحتاج إلى إنشاء قائمة انتظار للتعامل مع الحمل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top