ブロンズバッジ5個につきシルバーバッジ1個

ユーザーがお互いを助けようとしている人々のために、ブロンズバッジであるUsers Helping Usersを作成しました。これは手動で付与されます(親切であろうとする試みと「私もです」を区別するため)。

ブロンズバッジ5つごとに、Invaluableというシルバーステージのバッジを授与したいと考えています。

私が考えたSQLは、適切な2人のユーザーを見つけますが、それぞれ1回だけです。

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

SQLに何か:magic_wand:魔法が足りないのでしょうか、それともSQLの外で乗算が行われるのでしょうか?

また、私の2人のユーザーが、5つの新しいブロンズバッジを獲得していなくても、毎日新しいバッジを獲得しないように、どのように計算が行われるのかがよくわかりません(これは毎晩トリガーで実行されます)。

私の検索で見つけられなかった、これに関するガイドはありますか?

さらに深く検索した結果、ガイドにたどり着きました。

バックフィルについてはまだ少し不明瞭ですが、(当然ながら!)テストインスタンスで試すことにしました。バックフィルは一晩かけて実行されると思うので、明日にはもっとわかるでしょう。

「複数回付与可能」にチェックを入れない限り、2回目(以上)に資格を得たとしても、一度しか付与されないはずです。:+1:


わかりました、あなたの投稿をより詳しく読み直し、あなたが目指していることをより明確に理解できたと思います。

現在のSQLに基づくと、それらのユーザーは、複数回付与できるようにしても、シルバーバッジは一度しか付与されません。

  • テストサイトに関連するバッジを作成しました(複数付与も許可しています)。
  • ブロンズを5つ付与し、バッジを付与するバックグラウンドジョブを実行しました(シルバーバッジは正常に付与されました :partying_face:)。
  • その後、BadgeGrantジョブを再度実行しましたが、シルバーバッジは2回目は付与されませんでした。
  • その後、ブロンズバッジを11に増やし、バッジ付与ジョブを再度実行しました。
  • 2つ目のシルバーバッジは付与されませんでした。

「複数回」確認しましたが、

本来2回付与されるべきところが、1回しか付与されていませんでした。

「いいね!」 1

それで… 12個の銅バッジを持つユーザーに、彼が当然受けるべき2つの銀バッジを与えるにはどうすればよいですか?

「いいね!」 1

それは良い質問ですが、すぐに答えがわかりません。 :slight_smile:

RANK を使用することを暫定的に考えていますが、当てずっぽうかもしれません… :thinking:


ラフなプロトタイプ...
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)

さて、2回目の試みとして ROW_NUMBER を使用します。

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

しかし、さらにテストしたところ、これはプレビューでは正しく機能しますが、実際の badge grant ジョブが実行されるときに複数回付与されません。理由はよくわかりません。 :thinking:

混乱してしまいました。お茶を飲んで立て直します。 :slight_smile:

「いいね!」 1

まあ…昨日、ユーザーにブロンズをあと4つ与えて、一晩実行すれば、彼が「獲得した」新しいバッジが少なくとも追加されるかどうかを確認しました。(残りは手作業で追いつかなければならないと思ったので、そうしました。)しかし、それさえも機能しませんでした。

クエリについてはお手伝いできませんが、Discourse AI ボットに質問することをお勧めします。上部にあるボットアイコンを選択してください。
image → GPT-4 → SQL Helper。

必要なことを伝えるだけでデータエクスプローラークエリを作成するのに非常に役立つことがわかりました。バッジクエリにも役立つと思います。

「いいね!」 1

誰もがそう持っているわけではないよ、Toni :shushing_face: 人を嫉妬させることになるよ。:slight_smile: (でも @ganncamp は持っているから、選択肢ではあるけどね)

でも…私のクエリは正しいと確信しているんだ。プレビューでは正しいものを選び出しているんだけど、「毎日更新」トリガーを使用すると、1つ以上は付与されないんだ。

「特定のトピックで5投稿ごと」のバッジを「ユーザーが投稿を作成または編集したとき」トリガーに基づいてテストするために、ほぼ同じ別のものを設定したんだ。そして、それは完璧に機能している。何が違うのか調べているところだよ…

もし何か気づいたことがあれば、比較のためにそのテストバッジのSQLを以下に示すね。

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

@tpetrov にアクセスできますが、試みはあまり実りませんでした。それとも、難しい質問をするのが得意なだけでしょうか?:laughing:

「いいね!」 1

少し調査・相談した結果、自動バッジ付与機能は、特定の投稿に基づいている場合にのみ複数のバッジを付与するようです。そのため、このようなタイプは最初のバッジしか付与されません(プレビューは誤解を招きます :frowning:)。

このようなケースでは、「昇格」バッジ(例えば、解決済みバッジなど)がうまく機能すると思います。例えば、30回でシルバー、100回でゴールドといったように、それが可能な代替案になるのではないでしょうか?

ですから…ブロンズバッジは投稿に基づいて付与されるにもかかわらず…それはカウントされないということですよね?

わかりません。質問を理解していないと思います。:laughing:

提案は、5つのバッジを見つけることではなく、バッジが付与された5つの投稿を見つけることだと思いますか?それはできます。すでに「バッジを付与する新しい投稿を見つける」レポートで、ほぼ完了しています。

うーん。:thinking: あなたが何をしようとしているのか分かりました。もう一度やってみましょう…


@ganncamp - 成功したかもしれません… :slight_smile:

ブロンズバッジAがポストレンチ経由で付与されるか、/admin/users/{user_id}/{username}/badgesページで理由を与えることで付与されることを考えると:

これは確かに可能だと思います。 :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))

AND post_id IS NOT NULLを追加することで、理由なしで付与された場合に保護され、壊れるのを防ぎます)

試してみたところ、GrantBadgeバックグラウンドジョブをトリガーして高速フォワードしたところ、テストユーザーはついにふさわしい完全なクレジットを受け取りました。 :slight_smile:

次に、5つの異なる投稿に対してさらに5つのバッジAを付与し、もう一度実行しました: :tada:

「いいね!」 3

@JammyDodgerさん、ありがとうございます! :tada: :tada: :tada:

テストインスタンスにこれを設定しました(あなたを信用していないわけではありません :joy:)。今週中に本番環境に適用したいと思っています! :star_struck:

そして…この探求で学んだことを、このチュートリアルに反映させるようお願いするのに良いタイミングでしょうか? :smiley:

もちろん。信頼し、検証するというのは、確かに賢明な選択です。 :slight_smile:

何か少し追加できるか見てみます。 :slight_smile: :+1:

「いいね!」 2

さて… 夜間にジョブが実行されたとき、
銅バッジ6個を持つ私のユーザーは銀バッジを1個獲得しました:white_check_mark:
銅バッジ13個を持つ私のユーザーは… 銀バッジを1個獲得しました:slightly_frowning_face:

チュートリアルのこの部分を見て、個別の明示的なバックフィルジョブは不要だと考えました。

毎日フルバックフィルが実行されるため、それを考慮に入れ、:backfill パラメータの処理を含める必要があります。

すでに銀バッジを1個以上獲得しているユーザーについては、どのようにすればそれらが授与されますか?手動で行う必要がありますか?

バックフィルは日次ジョブです。「日次更新」トリガーは基本的にその通りですが、他のトリガーはもっと「その場で」実行されます(例:バッジが「ユーザーが投稿を作成または編集したとき」を使用する場合、付与されるのを一晩待つ必要はありません)。

バッジのスクリーンショットをここに貼り付けていただければ、何が違うのか確認できます。

どうぞ:

ちなみに、いくつか確認したのは…何をしているか分からないからです :joy:

「いいね!」 1

そして、13個の「バッジA」を持つユーザーは、/admin/users/{user_id}/{username}/badges ページを見ると、理由が入力されていますか?

重要な部分は同じですね。 :slight_smile: 他のものは依然として正当ですが、オプションです。

ステージングサイトで実行していますか、それともセルフホストのテストサイトで実行していますか?

すごい!謎が解けました!

私は、このジョブが(私の)早朝に実行されると思い込んでいました。

実際、元々は理由もなくこのユーザーにバッジを付与していたので、昨日すべて取り消し、彼の投稿を掘り起こして再付与しました。ジョブはその付与の最中に実行されました。

ちなみに、これは私のステージングサイトでのことです。

数時間後には2番目のバッジが付与されると思いますが、一度に複数のバッジが付与されるのを見てみたいです。シルバーを剥奪したら、そうなりますか?彼は…2時間後に新しいシルバーを2つ付与されますか?

「いいね!」 1