דילוג לתוכן
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
כיווץ
תחומים

תחומים - פורום חרדי מקצועי

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
  1. דף הבית
  2. תכנות
  3. עדכון אטומי בmongodb

עדכון אטומי בmongodb

מתוזמן נעוץ נעול הועבר תכנות
8 פוסטים 3 כותבים 308 צפיות
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • I מנותק
    I מנותק
    ivrtikshoret
    כתב ב נערך לאחרונה על ידי ivrtikshoret
    #1

    שלום וברכה
    יש לי טבלה (collection) בmongodb שמכיל אובייקטים בצורה הזאת:

    {
    key:'key1',
    value:'3',
    exp:'2024-10-07T09:38:21.714Z',
    valueAfetrExp:'1'
    }
    

    הפונקצייה אמור להיות העלאת ה value בסכום מסויים בצורה אטומית כך שלא יפקשש בקשות מקבילות על אותו key
    הוא אמור להעלות רק אם הexp עדיין לא עבר ובמידה שכן שיעדכן את value במה שכתוב ב valueAfetrExp
    במידה שלא כתוב כלום ב valueAfetrExp הוא אמור למחוק את האובייקט.

    ניסיתי להשתמש עם transaction הבעייה היא שבסקייל גבוה כל בקשה יכול להיות גם עשר דקות או אפילו יותר.
    יש פיתרון אחר?

    אני מצרף חלק מהקוד של העדכון שיש לי כיום:

    const setKey = async (key: string, newValue: string) => {
        await client.withSession(async session => {
            await session.withTransaction(async () => {
                const oldData = await Data.findOne({ key: 'key1' }, { session });
                if (!oldData) throw new Error('Key not found');
                //בדיקה אם עבר כבר הזמן
                if (oldData.exp && checkIfExpIsOver(oldData.exp)) {
                    //הצבת הערך שיש ב valueAfetrExp ואם אין אז למחוק את האובייקט.
                } else {
                    await Data.updateOne({ _id: oldData._id }, {
                        $set: {
                            value: String(Number(oldData.value) + Number(newValue))
                        }
                    }, { session });
                }
            });
        });
    }
    
    צדיק תמיםצ תגובה 1 תגובה אחרונה
    0
    • צדיק תמיםצ מנותק
      צדיק תמיםצ מנותק
      צדיק תמים
      השיב לivrtikshoret ב נערך לאחרונה על ידי
      #2

      @ivrtikshoret כתב בעדכון אטומי בmongodb:

      ניסיתי להשתמש עם transaction הבעייה היא שבסקייל גבוה כל בקשה יכול להיות גם עשר דקות או אפילו יותר.

      מה הכוונה? תוכל לפרט?

      Don’t comment bad code — rewrite it." — Brian W. Kernighan and P. J. Plaugher"
      טיפים

      I תגובה 1 תגובה אחרונה
      0
      • I מנותק
        I מנותק
        ivrtikshoret
        השיב לצדיק תמים ב נערך לאחרונה על ידי ivrtikshoret
        #3

        @צדיק-תמים כתב בעדכון אטומי בmongodb:

        מה הכוונה? תוכל לפרט?

        מה אתה רוצה שאני יפרט?
        הוספתי את הקוד שמעדכן בפוסט הראשון

        צדיק תמיםצ תגובה 1 תגובה אחרונה
        1
        • צדיק תמיםצ מנותק
          צדיק תמיםצ מנותק
          צדיק תמים
          השיב לivrtikshoret ב נערך לאחרונה על ידי צדיק תמים
          #4

          @ivrtikshoret במחשבה נוספת, מה שאתה צריך זה לא טרנזקציה אלא להשתמש בinc, לא?
          ולא ממש הבנתי את תפקיד הexp, אם הוא נועד למחיקה אחרי זמן מסוים, עדיף לעשות את זה דרך אינדקס TTL

          Don’t comment bad code — rewrite it." — Brian W. Kernighan and P. J. Plaugher"
          טיפים

          I תגובה 1 תגובה אחרונה
          1
          • I מנותק
            I מנותק
            ivrtikshoret
            השיב לצדיק תמים ב נערך לאחרונה על ידי
            #5

            @צדיק-תמים כתב בעדכון אטומי בmongodb:

            @ivrtikshoret במחשבה נוספת, מה שאתה צריך זה לא טרנזקציה אלא להשתמש בinc, לא?
            ולא ממש הבנתי את תפקיד הexp, אם הוא נועד למחיקה אחרי זמן מסוים, עדיף לעשות את זה דרך אינדקס TTL

            לגבי האופצייה הראשונה אני צריך לבדוק לפני האם התפוגה עבר כבר וכן מה שכתבתי על השאלה השנייה
            לגבי השאלה השנייה לא תמיד הוא מוחק אלא אם יש משהו ב valueAfetrExp אני לא מוחק אלא מציב ב value את מה שכתוב ב valueAfetrExp ולכן אני לא יכול להשתמש עם אינדקס TTL

            צדיק תמיםצ תגובה 1 תגובה אחרונה
            0
            • צדיק תמיםצ מנותק
              צדיק תמיםצ מנותק
              צדיק תמים
              השיב לivrtikshoret ב נערך לאחרונה על ידי
              #6

              @ivrtikshoret אני לא מבין למה הטרנזציה איטית, אבל אתה יכול לבצע את כל הלוגיקה דרך mongodb באמצעות מה שנקרא aggregation pipeline, ואז זה אטומי בלי טרנזציה, משהו כזה (גילוי נאות, השאילתה נכתבה ע"י claude.ai) :

              const setKey = async (key: string, newValue: string): Promise<void> => {
                  const currentDate = new Date();
                  const newExp = new Date(Date.now() + 24 * 60 * 60 * 1000); // 24 שעות מעכשיו
              
                  const result = await Data.findOneAndUpdate(
                      { key: key },
                      [
                          {
                              $set: {
                                  isExpired: { $gt: [currentDate, '$exp'] }
                              }
                          },
                          {
                              $set: {
                                  value: {
                                      $cond: {
                                          if: { $not: ['$isExpired'] },
                                          then: { $add: [{ $toInt: '$value' }, { $toInt: newValue }] },
                                          else: {
                                              $cond: {
                                                  if: { $ne: ['$valueAfterExp', null] },
                                                  then: '$valueAfterExp',
                                                  else: '$value'
                                              }
                                          }
                                      }
                                  },
                                  exp: {
                                      $cond: {
                                          if: { $not: ['$isExpired'] },
                                          then: '$exp',
                                          else: newExp
                                      }
                                  },
                                  valueAfterExp: {
                                      $cond: {
                                          if: { $not: ['$isExpired'] },
                                          then: '$valueAfterExp',
                                          else: null
                                      }
                                  }
                              }
                          },
                          {
                              $unset: 'isExpired'
                          }
                      ],
                      { returnDocument: 'after' }
                  );
              
                  if (!result.value) {
                      throw new Error('Key not found');
                  }
              
                  // מחיקת האובייקט אם אין valueAfterExp ופג תוקפו
                  if (checkIfExpIsOver(result.value.exp as Date) && !result.value.valueAfterExp) {
                      await Data.deleteOne({ _id: result.value._id });
                  }
              };
              

              Don’t comment bad code — rewrite it." — Brian W. Kernighan and P. J. Plaugher"
              טיפים

              תגובה 1 תגובה אחרונה
              0
              • yossizY מנותק
                yossizY מנותק
                yossiz
                כתב ב נערך לאחרונה על ידי
                #7

                @ivrtikshoret בעניותי עוד לא הבנתי למה אי אפשר להשתמש ב-inc
                הבדיקה אם התאריך פג לא צריך להיות אטומי

                📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

                I תגובה 1 תגובה אחרונה
                2
                • I מנותק
                  I מנותק
                  ivrtikshoret
                  השיב לyossiz ב נערך לאחרונה על ידי ivrtikshoret
                  #8

                  @yossiz
                  בעצם מה שאתה אומר דבר ראשון לשלוף את הנתונים הקיימים כרגע ולבדוק את התוקף במידה שכרגע אנחנו עדיין לפני התוקף אז לבצע עדכון עם inc,
                  צודק אני מנסה לחשוב למה לא עשיתי את זה,
                  בנתיים ננסה לעשות את זה אם זה יעבור את הטסטים אז מצוין, תודה מראש!

                  תגובה 1 תגובה אחרונה
                  1

                  בא תתחבר לדף היומי!
                  • התחברות

                  • אין לך חשבון עדיין? הרשמה

                  • התחברו או הירשמו כדי לחפש.
                  • פוסט ראשון
                    פוסט אחרון
                  0
                  • דף הבית
                  • קטגוריות
                  • פוסטים אחרונים
                  • משתמשים
                  • חיפוש
                  • חוקי הפורום