店名の照合で起きた4つの取り違え:表記ゆれ・あいまいな地図検索・「同じ応募ページ=同じ店」・1ページ複数案件

English version

トレカダッシュ 開発の記録 / 4 件のまとめ

トレカダッシュは、店の告知や X の投稿から「どの店の、どの抽選か」を読み取って並べます。いちばん間違えやすいのが店の名前でした。同じ店が別の名前で書かれ、別の店が同じリンクを使い、あいまいな名前は地図で遠くの場所に化けます。ここには、店の照合で実際に起きた 4 つの取り違えと、その直し方を、起きた順にまとめました。

それぞれの節は、もとは別々に公開していた記録です(2026 年 10 月から)。数字と出典は、その時の作業の記録のままです。テーマごとに読めるよう、1 つの記事にまとめ直しました(2026 年 11 月 7 日)。

「ヤマダ電機」と「ヤマダデンキ」:表記ゆれと重複の原因は 3 つ重なっていた(包含だけの比較・59 秒の差・手動専用のジョブ)

2026 年 10 月 17 日の記録。

iOS アプリ「トレカダッシュ」の記事では、同じ店の名前が、「ヤマダ電機」と「ヤマダデンキ」のように、書き方がバラバラでした。報告は、2 つ来ました。「表記揺れしている」「同じ理由で、記事が重複している」。指示は、「他の店でも同じことが起きないように、徹底的に」でした。

この記事は、原因が 3 つ重なっていたことと、「言い換えの表を作らず、一般則で直す」過程の記録です。

この記事は、2026 年 8 月 25 日の作業の記録から書いています。

原因は、3 つ重なっていた

  1. 店名の比較が、「含んでいるか」だけだった。「ヤマダ電機」と「ヤマダデンキ」は、どちらも、もう一方を含まないので、別の店になります。
  2. 締切を、ミリ秒まで一致で比べていた。同じ「8/26 まで」でも、まとめサイト由来は 23:59:00、X 由来は 23:59:59 で、59 秒の差のせいで、重複と判定されませんでした。実データの 4 商品が、これでした。
  3. 重複を整理するジョブが、手動で動かす専用で、一度も自動で走っていなかった。「一度きりの修復」のつもりで作っても、記事は毎日入るので、重複も毎日生まれます。

直し方:言い換えの表は、作らない

店名の比較のキー(storeNameComparisonKey)を作りました。法人格、記号、空白、全角と半角を落とし、カタカナをひらがなにし、「電機、電器、でんき」を 1 つに寄せます。

店名の言い換えの表は、作りません。新しい店が増えるたびに、再発するからです。読みが同じになる書き分けを、まとめる一般則にしました。

テストで見つけた、2 つの危険

どちらも、直したあとに、テストで見つけました。

実データ 17 パターンで確かめて、食い違いは 0 件でした。

実行結果

前後
店名の表記揺れ2 件0 件
同じ商品・同じ締切・同じ店の重複7 組0 組

ついでに、「○○@スタッフ募集中」のような宣伝文の付いた店名 23 件も、そろいました。重複のとき、残す側は、値段と当落発表日を持つほうです。

分かったこと

一覧で直さず、一般則で直す。そして、直す処理は、自動で走らせる。

あいまいな店名で地図を引くと、日本の真ん中の静岡が返る:チェーン名を並べず、Google 自身の答えで判定した

2026 年 10 月 17 日の記録。

iOS アプリ「トレカダッシュ」には、店の位置を地図に出して、近い順に並べる機能があります。「位置情報が、静岡になる」という報告が来ました。店の位置は、店の名前を Google の地図の検索(Places API)に渡して、座標を取っています。

原因は、あいまいな店名で問い合わせると、Google が、日本全体の真ん中(静岡と愛知)を返すことでした。この記事は、その実測と、「チェーン名を並べない」直し方の記録です。

この記事は、2026 年 8 月 25 日の作業の記録から書いています。

実測:あいまいな名前の答えは、静岡と愛知

検索には、「日本全体の矩形」を、位置の手がかり(locationbias)として渡しています。名前があいまいで、決め手が無いと、Google は、その矩形の真ん中を返します。それが、静岡と愛知です。API で実測しました。

問い合わせた名前Google の答え
ヤマダデンキヤマダデンキ テックランド浜松本店(静岡県)
サンエー㈱サンエー化研 掛川工場(静岡県)
ホビーステーショントレカステーション豊橋店(愛知県)
ブックオフBOOKOFF 掛川店(静岡県)
晴れる屋晴れる屋 静岡店(静岡県)
おむすびお米とおむすび むらせ 浜松広沢店(静岡県)

「サンエー」は、小売のチェーンのことでしたが、答えは、同じ名前の、別の会社の工場でした。

直し方:チェーン名を並べず、Google 自身の答えで判定する

「あいまいなチェーン名の一覧」を作る方式は、採りませんでした。新しいチェーンが増えるたびに、再発します。代わりに、Google が返した答え自身で、信用できるかを判定する関数(geocodeMatchIsTrustworthy)を作りました。

  1. 問い合わせた名前が、返ってきた店名の頭でしかなく、残りが支店名なら、不採用。(ヤマダデンキ → …テックランド浜松本店)「店」が付いただけなら、同じ店。
  2. 店名に、支店の手がかり(〇〇店、館、モール…)があれば、従来どおり採用。
  3. 返ってきた店名が、問い合わせた名前と同じ、または、その一部なら採用。(カードショップクラクラ、ゲームショップ プラスアルファ)逆向きは採用しない。(サンエー ⊂ ㈱サンエー化研は、別の会社。)
  4. それ以外は、店名と住所が 2 文字以上重なっているかで判定。(池袋、戸塚、札幌、高田馬場などを名前に持つ店は、ここで通る。)

実データの 25 パターンで確かめると、誤り 9 件は全部不採用、正しい 16 件は全部採用でした。取りこぼしは、ローマ字表記の 1 件だけでした。

すでに、間違った位置が焼き付いていた記事 30 件と、店の位置のキャッシュ 22 件は、消して、解決し直しました。キャッシュを消すと、1 店につき 1 回だけ、API を呼び直します。

同じ日に見つけた、似た話:通知の店名が「ライヴポケット」

「通知の店名が、ライヴポケットになる」という報告もありました。店名が取れなかったときに、最後の受け皿として、カテゴリ(「ライヴポケット」)が通知に出ていました。ライヴポケットは、応募を受け付ける場であって、店ではありません。そこで、分からないときは、null を返すようにしました。呼び出し側は、店名が無ければ記事の題名を使います。ライヴポケットの題名は、「キデイランド ららぽーと富士見店 …」のように、店名から始まるので、そのほうが正しく伝わります。

分かったこと

外部の答えは、答え自身で、信用できるかを確かめる。

「同じ応募ページ」なら「同じ店」と決めつけていた:店名が別の店になった記事 52 件

2026 年 10 月 17 日の記録。

iOS アプリ「トレカダッシュ」で、「利用者には、違う店の抽選に見える」という不具合が見つかりました。仙台駅前店の記事が「新宿南口店」と表示され、八王子本店の記事が「能代店」と表示されていました。52 件でした。

原因は、「同じ応募ページなら、同じ店だ」という、前提の間違いでした。

数字は、2026 年 9 月 7 日の作業の記録から書いています。

症状:店名が、別の店の名前になっていた

同じチェーンの、別の支店の名前が、記事に書かれていました。利用者から見ると、「仙台の店の抽選」のつもりで開いたら、「新宿の店」と書いてある、という状態です。52 件が、そうなっていました。

真因:応募ページが同じでも、店は同じとは限らない

「同じ応募ページを持つ記事の、店名と締切を、そろえる」処理がありました。同じ抽選なら、締切も同じ。同じ店なら、名前も同じ。そう考えて、グループの中でいちばん質の高い記事の店名を、全員に書き写していました。

この前提が、成り立っていませんでした。実データで数えると、こうでした。

応募ページ共有している店
ある応募ページ(1)15 の別々の店(仙台、浜松、前橋、紫波、蒲郡、広島、など)
ある応募ページ(2)同じチェーンの9 支店
ある応募ページ(3)ある店と、別のチェーン 3 つ(チェーンすら別)

チェーン全体で 1 つの応募ページを使う店は、普通にあります。同じページでも、店はそれぞれ違います。

この種の事故は、隠す側では、すでに一度起きていて、そちらには関門が入っていました(あるチェーンの 51 支店の件)。ところが、店名を書き写す側には、入れ忘れていました。同じ判定を使う、別の入口に、同じ修正を当てていなかったのです。

「座標が食い違う」だけの関門では、足りなかった

最初は、「座標(店の位置)が食い違うなら、別の店」という関門で守ろうとしました。ところが、片方の記事しか座標を持っていない組では、「確実に別の場所」の判定が false になり、素通りしてしまいます。実際に、書き込まずに結果だけを見る下見(ドライラン)で、ある 3 つの別のチェーンの店が、全部「晴れる屋 2 秋葉原タワー店」に書き換わるところでした。

恒久対策は、判定の向きを逆にすることでした。「別の店だと確かめられたとき、そろえない」ではなく、「同じ場所だと確かめられたときだけ、そろえる」。両方に座標があり、一致しているときだけ、そろえます。座標が無い、または食い違う組は、「同じ店だと分からない」ので、各記事が自分で名乗る名前を尊重します。締切は、同じ応募ページの同じ抽選なので、今までどおりそろえます。

すでにできている 52 件を、戻した

書き換えられた店名の、元の値は、保存していませんでした。手がかりは、この処理が一度も触らない項目(category)でした。記事が作られたときに、その記事自身の出どころ(店の X アカウント、まとめの行)から入ります。52 件をすべて目で確かめると、category のほうが、出どころと一致していました。

座標は、根拠にできませんでした。座標は店名から引き直す仕組みなので、店名が書き換えられたあとは、間違った名前の座標になっています(category は札幌駅前店なのに、座標は新宿)。だから、戻すときに座標も捨てて、引き直しの対象に戻しました。

ついでに見つかった、「行列に並べない」バグ

座標を引き直そうとしたら、4 件とも、順番が回ってきませんでした。位置情報を直す処理には、列が 2 つありました。

列中身
正面(60 件ずつ)座標がほしい記事
再挑戦(300 件の窓)実測 658 件。うち、座標が本当に無いのは34 件だけ

再挑戦の列に、解決できた記事まで入れていました(成功したときに、印を「false」に書いていたため、列に残る)。624 件の「もう用のない記事」が、窓を埋めて、本当に必要な 34 件に、順番が回りませんでした。

直し方は、解決できたら、印そのものを消すことです。どちらの列にも並びません。

分かったこと

「同じ」と決めつける前に、「同じ」だと確かめる。

「1 ページ = 1 案件」ではなかった:1 つのフォームで 6 商品を受け付ける店の記事が、リンクが同じというだけで消されていた

2026 年 10 月 17 日の記録。

iOS アプリ「トレカダッシュ」で、「複数の商品を受け付けている抽選なのに、1 件しか記事が無い」という報告が、2 回、来ました。1 回目に直したつもりでしたが、2 回目が来ました。

この記事は、その真因と、同じ時期に見つけた、「作った項目を、アプリが一度も読んでいなかった」話の記録です。

この記事は、2026 年 8 月 25 日の作業の記録から書いています。

真因:リンクだけで、重複と決めていた

1 回目の報告で、「リンクが同じだから、重複扱いされている」ところまでは、直しました。しかし、すでにある記事が、隠れたままだったので、同じ指摘を、また受けました。

犯人は、runHideDuplicateLinkArticles、つまり、リンクだけで、重複と判断するジョブでした。

実データは、こうでした。ある通販店は、1 つの Google フォームで、6 つの商品の抽選を受け付けています。6 件の記事は、全部、同じ URL です。このジョブが、そのうち 5 件を「重複」として、消していました。利用者からは、1 商品ぶんしか、見えません。

直し方は、まとめる単位を、リンクから、リンク + 商品に変えることでした。同じリンクでも、商品が違えば、別の案件です。商品が分かっていない記事どうしは、区別する手がかりが無いので、これまでどおり、リンクだけで、重複とみなします。

「1 ページ = 1 案件」という前提は、トレカの抽選では成り立ちません。1 つの申込みフォーム、1 つの告知のページで、複数の商品を受け付ける店は、普通にあります。

すでに隠されていた記事は、同じリンクの表示中の記事と、商品または題名が違うものに限って、表示に戻しました(7 件)。ある通販店の 5 件(6 商品すべてが表示される)、大手のゲーム店 1 件、別のチェーン 1 件です。

サーバが作った「応募枠」を、アプリが一度も読んでいなかった

8 月 23 日から、サーバーは、応募の条件を AI で読んで、「応募枠」(entryTiers)を取り出していました。「プレイヤーズクラブ:本人認証済みの枠と、未認証の枠」「A グループと B グループ」「ビックカメラの Suica カード会員限定」といったものです。実データにも、ちゃんと入っていました。

ところが、iOS のアプリが、この項目を、一度も読んでいませんでした。AI の費用だけを払って、利用者には、見えない状態です。アプリに、項目を足し、詳細の画面に、「応募枠」として表示するようにしました。

サーバーとアプリの項目の突き合わせは、コマンドで見つかります。アプリが読む項目を、ソースから機械的に抜き出し(grep)、Firestore の実データと比べます。

商品の一覧に、告知文が混ざっていた

「ONE PIECE カードゲームコーナー【事前入店申込・抽選】8 月 31 日(月)JUMP SHOP 東京駅店」のような、イベントの告知が、商品として登録されていました。

言い回しを並べる方式は、追いつきません。そこで、具体的な日付という、一般的な規則で弾きました。トレカの商品名に、「8 月 31 日」のような暦の日付は入りません。「Vol.3」「第 2 弾」「2025 年 19 号」は日付ではないので、影響しません。10 個のパターンで試して、食い違いは 0 件でした。すでにある 6 件を削除しました。

分かったこと

前提を疑う。作ったものが、使われているかを確かめる。

それぞれの要点

ほかの記録は、Notes の一覧から、テーマごとに読めます。トレカダッシュそのものは、作品ページに書いています。

ほかの記録

コメント

感想や、記事の間違いの指摘は、ここへ。書くには、GitHub のアカウントが要ります。

押すと、giscus(giscus.app)と GitHub に接続します。押さなければ、接続しません。詳しくはプライバシーポリシーに書いています。