Una insignia de plata por _cada_ 5 insignias de bronce

Hemos creado una insignia de bronce, Usuarios Ayudando Usuarios, para las personas que intentan ayudar a otros usuarios. Se otorga manualmente (para poder diferenciar entre intentos de ser útil y “yo también”).

Por cada 5 insignias de bronce, queremos otorgar una insignia de astilla, Invaluable.

El SQL que he creado encuentra a los dos usuarios correctos, pero solo una vez cada uno:

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

¿Me falta algo de :magic_wand: magia en mi SQL, o el multiplicador ocurre fuera del SQL?

Además, no me queda nada claro cómo se realizan los cálculos para que mis dos usuarios no obtengan nuevas insignias todos los días (esto se ejecutará con un disparador nocturno) incluso si no han obtenido 5 nuevos bronces.

¿Hay alguna guía sobre esto que mi búsqueda no haya encontrado?

Una búsqueda más profunda me llevó a un hilo que me condujo a la guía

Lo de la carga masiva todavía está un poco confuso, pero he decidido (obviamente) probar esto en nuestra instancia de prueba. Supongo que la carga masiva se ejecuta durante la noche, así que sabré más mañana.

A menos que marques ‘Se puede otorgar varias veces’, no debería otorgarse más de una vez, incluso si califican para ello una segunda (o más) vez. :+1:


De acuerdo, he vuelto a leer tu publicación más detenidamente y creo que tengo una idea más clara de lo que buscas.

Según el SQL actual, esos usuarios solo recibirán la insignia de Plata una vez, incluso si permites que se otorgue varias veces:

  • He creado las insignias relevantes en mi sitio de prueba (incluyendo permitir múltiples)
  • Otorgué 5 de Bronce y ejecuté el trabajo en segundo plano para otorgar la insignia (¡insignia de Plata otorgada con éxito! :partying_face:)
  • Luego ejecuté el trabajo BadgeGrant nuevamente y no se les otorgó la Plata por segunda vez
  • Luego aumenté sus insignias de Bronce a 11 y volví a ejecutar el trabajo de concesión de insignias
  • No se otorgó una segunda insignia de Plata

Revisé ‘varias veces’

pero solo se concedió una vez, aunque debería haber sido dos veces

1 me gusta

Entonces… ¿qué tengo que hacer para que mi usuario, con 12 insignias de bronce, reciba las 2 de plata que merece?

1 me gusta

Esa es una buena pregunta a la que no sé la respuesta de inmediato. :slight_smile:

Tentativamente estoy pensando en algo que use RANK, pero puede que esté intentando cosas imposibles… :thinking:


Prototipo aproximado...
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)

De acuerdo, un segundo intento usando ROW_NUMBER en su lugar:

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

Aunque, tras más pruebas, esto funciona correctamente en la vista previa pero no se está concediendo varias veces cuando se ejecuta el trabajo real de badge grant. No estoy muy seguro de por qué. :thinking:

Me he confundido. Voy a tomar una taza de té y a reagruparme. :slight_smile:

1 me gusta

Bueno… Le di a mi usuario otros 4 bronces ayer para ver si la ejecución nocturna al menos agregaría la nueva insignia que acababa de “ganar”. (Pensé que si tenía que ponerme al día con el resto a mano, podría hacerlo). Pero ni siquiera eso funcionó.

No puedo ayudarte con la consulta, pero te sugiero que le pidas ayuda al bot de Discourse AI: selecciona el icono del bot en la parte superior
image → GPT-4 → SQL Helper.

Lo he encontrado muy bueno para crear consultas de Data Explorer solo diciéndole lo que necesito y supongo que puede ayudar con las consultas de insignias.

1 me gusta

No todo el mundo tiene eso, Toni :shushing_face: Vas a dar envidia a la gente. :slight_smile: (aunque @ganncamp sí lo tiene, así que es una opción)

Pero… estoy bastante segura de que mi consulta es correcta. Selecciona las correctas en la Vista previa, pero simplemente no otorga más de una cuando se usa el disparador ‘Actualizar diariamente’.

He configurado otra casi idéntica para probarla basándome en una insignia de ‘cada 5 publicaciones en un tema específico’ usando el disparador ‘cuando un usuario crea o edita una publicación’, y esa funciona perfectamente. Estoy investigando cuál puede ser la diferencia…

Aquí está el SQL para esa insignia de prueba para comparar si alguien puede detectar algo:

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 Me gusta

Tengo acceso a él @tpetrov pero mis intentos de usarlo han sido… menos que fructíferos. ¿O tal vez solo soy bueno haciendo preguntas difíciles? :laughing:

1 me gusta

Tras un poco de exploración y consulta, parece que el concesionario automático de insignias solo otorgará varias insignias si se basan en publicaciones específicas. Por lo tanto, estos tipos solo otorgarán la primera insignia (la vista previa es engañosa :frowning:).

Creo que en casos similares las insignias de ‘escalada’ pueden funcionar bien (como las de Resuelto). Por lo tanto, una Plata por 30 y una Oro por 100, por ejemplo, ¿si esa pudiera ser una alternativa viable?

Entonces… aunque las insignias de bronce se otorgan según las publicaciones… eso no cuenta, ¿verdad?

No lo sé. Creo que no entiendo la pregunta. :laughing:

Supongo que la sugerencia no es encontrar 5 insignias, sino 5 publicaciones donde se haya otorgado una insignia. Puedo hacer eso. Ya lo he hecho más o menos en mi informe “encontrar nuevas publicaciones para otorgar insignias”.

Hmm. :thinking: Creo que entiendo a dónde quieres llegar. Déjame intentarlo de nuevo…


@ganncamp - Creo que podemos tener algo de éxito… :slight_smile:

Basándome en que la Insignia de Bronce A se otorga a través de la llave inglesa de publicación o dando una razón en la página /admin/users/{user_id}/{username}/badges:

Entonces creo que esto es realmente posible. :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))

(Añadir AND post_id IS NOT NULL lo protege si alguien recibe una sin razón, de lo contrario se rompe)

Lo acabo de probar y he avanzado activando el trabajo en segundo plano GrantBadge y mi usuario de prueba finalmente ha recibido el crédito completo que merece. :slight_smile:

Luego le otorgué 5 Insignias A más por 5 publicaciones diferentes y lo ejecuté de nuevo: :tada:

3 Me gusta

¡Gracias @JammyDodger! :tada: :tada: :tada:

Lo he configurado en mi instancia de prueba (no es que no confíe en ti :joy:) y espero ponerlo en producción esta semana. :star_struck:

Y… ¿es un buen momento para pedir que el tutorial se actualice con las cosas que has aprendido en esta búsqueda? :smiley:

Claro. Confiar, pero verificar es sin duda una elección inteligente. :slight_smile:

Veré si puedo añadir algo. :slight_smile: :+1:

2 Me gusta

Bueno… cuando el trabajo se ejecutó durante la noche,
mi usuario con 6 bronces obtuvo 1 plata :white_check_mark:
mi usuario con 13 bronces obtuvo… 1 plata :slightly_frowning_face:

Esta parte del tutorial me hizo pensar que un trabajo de relleno separado y explícito no era necesario

Dado que diariamente se ejecuta un relleno completo independientemente, debes tener eso en cuenta e incluir el manejo del parámetro :backfill.

Para los usuarios que ya han ganado más de 1 plata, ¿cómo consigo que se otorguen? ¿Tengo que hacerlo manualmente?

La retroalimentación es el trabajo diario. El disparador ‘Actualizar diario’ es esencialmente eso, mientras que los otros disparadores son mucho más ‘en el momento’ (por ejemplo, si una insignia usara ‘cuando un usuario crea o edita una publicación’, no necesitaría esperar toda la noche para que se le otorgara).\n\n¿Puedes poner una captura de pantalla de tu insignia para que pueda ver qué puede ser diferente?\n\n

Aquí tienes:

Por cierto, algunas de estas cosas las comprobé porque… no sé lo que estoy haciendo :joy:

1 me gusta

¿Y tu usuario con 13 ‘Insignia A’ tiene las razones completas cuando miras su página /admin/users/{user_id}/{username}/badges?

Tienes los puntos importantes iguales. :slight_smile: Los otros son legítimos, pero opcionales.

¿Estás ejecutando esto en tu sitio de staging o en un sitio de prueba autoalojado?

¡Woah! ¡Misterio resuelto!

Suponía que el trabajo se ejecutaba en las primeras horas de la madrugada (de mi parte).

De hecho, originalmente le había otorgado insignias a este usuario sin motivos, así que ayer las revocé todas, desenterré publicaciones suyas y las volví a otorgar. El trabajo se ejecutó en medio de mi concesión.

Esto es en mi sitio de staging, por cierto.

Supongo que la segunda insignia se otorgará en unas pocas horas, pero me gustaría ver múltiples insignias otorgadas a la vez. ¿Sucederá eso si revoco la de plata? ¿Se le otorgarán 2 nuevas de plata en… 2 horas?

1 me gusta