Un badge d'argento per ogni 5 badge di bronzo

Abbiamo creato un badge di bronzo, Users Helping Users, per le persone che cercano di aiutare altri utenti. Questo viene assegnato manualmente (per poter distinguere tra tentativi di essere d’aiuto e “anch’io”).

Per ogni 5 badge di bronzo, vogliamo assegnare un badge d’argento, Invaluable.

L’SQL che ho trovato individua i due utenti giusti, ma solo una volta ciascuno:

SELECT user_id, current_timestamp AS granted_at 
FROM user_badges
WHERE badge_id = 110 -- Users Helping Users
    AND (:backfill OR user_id IN (:user_ids))
GROUP BY user_id
HAVING COUNT(*) >= 5

Mi manca qualche :magic_wand: magia nel mio SQL, o il moltiplicatore avviene al di fuori dell’SQL?

Inoltre, non mi è chiaro come avvenga il calcolo in modo che i miei due utenti non ricevano nuovi badge ogni giorno (questo verrà eseguito con un trigger notturno) anche se non hanno ricevuto 5 nuovi badge di bronzo.

Esiste una guida a questo che la mia ricerca non ha trovato?

Ok, una ricerca più approfondita mi ha portato a una traccia che mi ha condotto a la guida

La questione del riempimento dei dati è ancora un po’ confusa, ma ho deciso di (ovviamente!) provare questo sulla nostra istanza di test. Suppongo che il riempimento dei dati venga eseguito durante la notte, quindi ne saprò di più domani.

A meno che tu non selezioni “Può essere concesso più volte”, non dovrebbe essere assegnato più di una volta, anche se si qualificano per la seconda (o più) volta. :+1:


Ok, ho riletto il tuo post più attentamente e penso di aver capito meglio cosa stai cercando di ottenere.

Sulla base dell’SQL attuale, a quegli utenti verrà assegnato il badge d’argento solo una volta, anche se permetti che venga concesso più volte:

  • Ho creato i badge pertinenti sul mio sito di test (incluso il permesso di concederli più volte)
  • Ho assegnato 5 badge di bronzo ed eseguito il processo in background per assegnare il badge (badge d’argento assegnato con successo :partying_face:)
  • Ho quindi eseguito nuovamente il processo BadgeGrant e non è stato assegnato loro un secondo badge d’argento
  • Ho quindi aumentato i loro badge di bronzo a 11 ed eseguito nuovamente il processo di assegnazione dei badge
  • Non è stato assegnato un secondo badge d’argento

Ho controllato ‘più volte’

ma è stato concesso solo una volta, anche se avrebbe dovuto essere due volte

1 Mi Piace

Quindi… cosa devo fare per far sì che al mio utente, con 12 badge di bronzo, vengano assegnati i 2 d’argento che merita?

1 Mi Piace

Questa è una buona domanda a cui non so rispondere immediatamente. :slight_smile:

Sto pensando provvisoriamente a qualcosa che utilizzi RANK, ma potrei star tirando a indovinare… :thinking:


Prototipo approssimativo...
WITH badge_count AS (

    SELECT 
        user_id,
        granted_at,
        RANK() OVER (PARTITION BY user_id ORDER BY granted_at ASC) AS rank
    FROM user_badges
    WHERE badge_id = 110

)

SELECT user_id, granted_at
FROM badge_count
WHERE rank IN (5,10,15,20,25,30,35,40,45,50)

Ok, un secondo tentativo usando ROW_NUMBER invece:

WITH badge_count AS (

    SELECT 
        user_id,
        granted_at,
        ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY granted_at ASC) AS row
    FROM user_badges
    WHERE badge_id = 110

)

SELECT user_id, granted_at
FROM badge_count
WHERE row % 5 = 0

Tuttavia, dopo ulteriori test, questo funziona correttamente nell’anteprima ma non viene concesso più volte quando viene eseguito il processo effettivo di badge grant. Non sono molto sicuro del perché. :thinking:

Mi sono confuso. Prenderò una tazza di tè e mi riorganizzerò. :slight_smile:

1 Mi Piace

Beh… ho dato al mio utente altri 4 bronzi ieri per vedere se l’esecuzione notturna avrebbe almeno aggiunto il nuovo badge che aveva appena “guadagnato”. (Ho pensato che se avessi dovuto recuperare il resto manualmente, avrei potuto.) Ma nemmeno quello ha funzionato.

Non posso aiutarti con la query, ma ti suggerisco di chiedere aiuto al bot Discourse AI: seleziona l’icona del bot in alto
image → GPT-4 → SQL Helper.

L’ho trovato molto utile nel creare query per Data Explorer semplicemente dicendogli di cosa ho bisogno e immagino che possa aiutare con le query per i badge.

1 Mi Piace

Non tutti ce l’hanno, Toni :shushing_face: Farai ingelosire la gente. :slight_smile: (anche se @ganncamp ce l’ha, quindi è un’opzione)

Ma… sono abbastanza sicuro che la mia query sia valida. Seleziona quelle giuste nell’anteprima, ma non ne assegna più di una quando si utilizza il trigger ‘Aggiorna giornalmente’.

Ne ho impostata un’altra quasi identica per testarla basata su un badge per ‘ogni 5 post in un argomento specifico’ utilizzando il trigger ‘quando un utente crea o modifica un post’ - e quella funziona perfettamente. Sto indagando su quale possa essere la differenza…

Ecco l’SQL per quel badge di test da confrontare se qualcuno riesce a individuare qualcosa:

WITH post_count AS (

    SELECT 
        user_id,
        id,
        created_at,
        ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at ASC) AS row
    FROM posts
    WHERE topic_id = 864

)

SELECT user_id, created_at granted_at, id post_id
FROM post_count
WHERE row % 5 = 0
  AND (:backfill OR id IN (:post_ids))

2 Mi Piace

Ci ho accesso @tpetrov ma i miei tentativi di usarlo sono stati… meno che fruttuosi. O forse eccello nel fare domande difficili? :laughing:

1 Mi Piace

Dopo un po’ di esplorazione e consultazione, sembra che il conceditore automatico di badge assegnerà più badge solo se sono basati su post specifici. Quindi questi tipi assegneranno solo il primo badge (l’anteprima è fuorviante :frowning:).

Penso che in casi simili i badge “escalating” possano funzionare bene (come quelli Solved). Quindi un argento per 30 e un oro per 100, per esempio, se questa potesse essere un’alternativa valida?

Quindi… anche se i badge di bronzo vengono assegnati in base ai post… non conta, vero?

Non lo so. Non credo di capire la domanda. :laughing:

Immagino che il suggerimento non sia di trovare 5 badge, ma 5 post in cui è stato assegnato un badge? Posso farlo. L’ho già fatto più o meno nel mio report “trova nuovi post a cui assegnare badge”.

Hmmm. :thinking: Penso di capire dove vuoi arrivare. Ci riprovo…


@ganncamp - Penso che potremmo avere un po’ di successo… :slight_smile:

Basandomi sul fatto che il Bronze Badge A viene assegnato tramite il post wrench o dando una motivazione nella pagina /admin/users/{user_id}/{username}/badges:

Allora penso che questo sia effettivamente possibile. :partying_face:

WITH badge_count AS (

    SELECT
        user_id,
        granted_at,
        post_id,
        ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY granted_at DESC) AS row
    FROM user_badges
    WHERE badge_id = 110
      AND post_id IS NOT NULL
)

SELECT user_id, granted_at, post_id
FROM badge_count
WHERE row % 5 = 0
  AND (:backfill OR post_id IN (:post_ids))

(Aggiungere AND post_id IS NOT NULL lo protegge nel caso in cui qualcuno ne riceva uno senza motivazione, altrimenti si rompe)

L’ho appena provato e ho accelerato attivando il job di background GrantBadge e il mio utente di test ha finalmente ricevuto il pieno riconoscimento che merita. :slight_smile:

Poi gli ho assegnato altri 5 Badge A per altri 5 post diversi e l’ho eseguito di nuovo: :tada:

3 Mi Piace

Grazie @JammyDodger! :tada: :tada: :tada:

L’ho configurato sulla mia istanza di test (non che non mi fidi di te :joy:) e spero di metterlo in produzione questa settimana! :star_struck:

E… è un buon momento per chiedere che il tutorial venga aggiornato con le cose che hai imparato in questa ricerca? :smiley:

Oh certo. Fidarsi, ma verificare è sicuramente una scelta intelligente. :slight_smile:

Vedrò se riesco ad aggiungere un piccolo qualcosa. :slight_smile: :+1:

2 Mi Piace

Beh… quando il processo è stato eseguito durante la notte,
il mio utente con 6 bronzi ha ottenuto 1 argento :white_check_mark:
il mio utente con 13 bronzi ha ottenuto… 1 argento :slightly_frowning_face:

Questa parte del tutorial mi ha fatto pensare che un processo di backfill separato ed esplicito non fosse necessario

Dato che ogni giorno viene eseguito un backfill completo, devi tenerne conto e includere la gestione del parametro :backfill.

Per gli utenti che hanno già guadagnato più di 1 argento, come posso farli assegnare? Devo farlo manualmente?

Il backfill è il processo giornaliero. Il trigger ‘Update Daily’ è essenzialmente solo questo, mentre gli altri trigger sono molto più ‘al momento’ (ad esempio, se un badge utilizzasse ‘quando un utente crea o modifica un post’, non avrebbe bisogno di aspettare la notte per essere assegnato).

Puoi allegare uno screenshot del tuo badge in modo che io possa vedere cosa potrebbe essere diverso?

Ecco qui:

Comunque, alcune di queste cose le ho controllate perché… non so cosa sto facendo :joy:

1 Mi Piace

E il tuo utente con 13 ‘Badge A’ ha i motivi compilati quando guardi la sua pagina /admin/users/{user_id}/{username}/badges?

Hai le parti importanti uguali. :slight_smile: Gli altri sono ancora legittimi, ma opzionali.

Lo stai eseguendo sul tuo sito di staging o su un sito di test self-hosted?

Woah! Mistero risolto!

Avevo ipotizzato che il job venisse eseguito nelle ore piccole del (mio) mattino.

Infatti, originariamente avevo concesso a questo utente badge senza motivi, quindi ieri li ho revocati tutti, ho recuperato i post suoi e li ho riassegnati. Il job è stato eseguito nel bel mezzo della mia assegnazione.

Questo è sul mio sito di staging, a proposito.

Suppongo che il secondo badge verrà concesso tra qualche ora, ma vorrei vedere più badge concessi contemporaneamente. Succederà se revocherò l’argento? Gli verranno concessi 2 nuovi argenti tra… 2 ore?

1 Mi Piace