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

> トレカの抽選情報を集めるアプリで、店名の照合が間違えた4つの記録。ヤマダ電機とヤマダデンキの表記ゆれ、地図検索が静岡を返す件、同じ応募ページでも別の店、1つのフォームで6商品。

- URL: https://koshinstudio.com/notes/tcg-store-matching/
- 公開: 2026-10-17
- 書いた人: Koshin（https://koshinstudio.com/about/）
- サイト: Koshin Studio

  English version (https://koshinstudio.com/en/notes/tcg-store-matching/)

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

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

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

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

  2026 年 10 月 17 日の記録。

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

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

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

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

- 店名の比較が、「含んでいるか」だけだった。「ヤマダ電機」と「ヤマダデンキ」は、どちらも、もう一方を含まないので、別の店になります。

- 締切を、ミリ秒まで一致で比べていた。同じ「8/26 まで」でも、まとめサイト由来は 23:59:00、X 由来は 23:59:59 で、59 秒の差のせいで、重複と判定されませんでした。実データの 4 商品が、これでした。

- 重複を整理するジョブが、手動で動かす専用で、一度も自動で走っていなかった。「一度きりの修復」のつもりで作っても、記事は毎日入るので、重複も毎日生まれます。

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

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

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

- 締切は、日付として（日本時間の日付で）比べ、代わりに販売の形式の一致を求めます。同じ日でも、先着と抽選は、別の案件だからです。

- 店名（sellerName）が無く、カテゴリにしか店名が無い記事も、対象に含めます。入荷情報のサイトや公式サイト由来の記事は、こちらが多く、まるごと見落としていました。

- 重複で隠すときは、必ず隠した印（hiddenByDuplicate）を付けます。

- 1 時間おきの定期実行を、足しました。

- 表記そのものも、実データの多数派に寄せます。正しい表記の一覧は、持ちません。同数のときは、カタカナ表記、次に文字列の順で固定して、実行のたびに答えが変わる、書き換え合戦を防ぎます。

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

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

- 「＠」の前だけをキーにすると、店名に＠を含む店が、極端に短いキーになる。「カードショップ＠ほ～む。鹿児島店」が「かーどしょっぷ」というキーになり、別の店と同一視されます。比較のキーでは、＠で切りません。（宣伝文が付いた名前は、包含の判定で拾えます。）

- 「片方がもう片方の先頭部分なら、同じ名前」にすると、支店名が消える。「イエローサブマリン」と「イエローサブマリン秋葉原店」が統合され、支店名が消えます。付け足しが、「＠」「【」「（」で始まる注記のときだけ、同じ名前とみなします。

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

### 実行結果

     | 前 | 後

      店名の表記揺れ | 2 件 | 0 件

      同じ商品・同じ締切・同じ店の重複 | 7 組 | 0 組

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

### 分かったこと

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

- 「含んでいるか」だけで比べない。書き分けは、含みません。

- ミリ秒まで一致で比べない。日付と、販売の形式で比べます。

- 「一度きりの修復」は、毎日生まれるものには足りない。自動で、定期的に走らせます。

- 言い換えの表は、新しい店で再発する。読みが同じになる、書き分けの一般則にします。

- 統合は、注記のときだけ。支店名を、消してはいけません。

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

  2026 年 10 月 17 日の記録。

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

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

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

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

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

    問い合わせた名前 | Google の答え

      ヤマダデンキ | ヤマダデンキ テックランド浜松本店（静岡県）

      サンエー | ㈱サンエー化研 掛川工場（静岡県）

      ホビーステーション | トレカステーション豊橋店（愛知県）

      ブックオフ | BOOKOFF 掛川店（静岡県）

      晴れる屋 | 晴れる屋 静岡店（静岡県）

      おむすび | お米とおむすび むらせ 浜松広沢店（静岡県）

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

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

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

- 問い合わせた名前が、返ってきた店名の頭でしかなく、残りが支店名なら、不採用。（ヤマダデンキ → …テックランド浜松本店）「店」が付いただけなら、同じ店。

- 店名に、支店の手がかり（〇〇店、館、モール…）があれば、従来どおり採用。

- 返ってきた店名が、問い合わせた名前と同じ、または、その一部なら採用。（カードショップクラクラ、ゲームショップ プラスアルファ）逆向きは採用しない。（サンエー ⊂ ㈱サンエー化研は、別の会社。）

- それ以外は、店名と住所が 2 文字以上重なっているかで判定。（池袋、戸塚、札幌、高田馬場などを名前に持つ店は、ここで通る。）

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

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

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

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

### 分かったこと

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

- 決め手が無いとき、外部サービスは「もっともらしい答え」を返す。日本の真ん中、静岡と愛知です。

- チェーン名の一覧を作らない。新しいチェーンが増えるたびに、再発します。

- 逆向きの包含は採用しない。サンエーは、サンエー化研の一部ではありません。

- 焼き付いた値は、消して解決し直す。キャッシュも一緒に。

- 分からないときは、null。間違った名前より、名前なしのほうが、まし。

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

  2026 年 10 月 17 日の記録。

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

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

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

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

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

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

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

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

    応募ページ | 共有している店

      ある応募ページ（1） | 15 の別々の店（仙台、浜松、前橋、紫波、蒲郡、広島、など）

      ある応募ページ（2） | 同じチェーンの9 支店

      ある応募ページ（3） | ある店と、別のチェーン 3 つ（チェーンすら別）

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

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

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

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

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

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

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

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

- 下見で 51 件、実行。

- 実行後、新たな上書きは 0 件（関門が効いている）。

- 表示中で、店名と category が食い違う記事は 2 件だけ。どちらも、同じ店の書き方の違いでした。

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

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

    列 | 中身

      正面（60 件ずつ） | 座標がほしい記事

      再挑戦（300 件の窓） | 実測 658 件。うち、座標が本当に無いのは34 件だけ

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

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

### 分かったこと

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

- リンクが同じでも、店は同じとは限らない。共有のページは普通にあります。

- 揃えるのは、同じだと確かめられたときだけ。確かめられないときは、触らない。

- 同じ事故の修正は、同じ判定を使う、すべての入口に。片方にだけ入れると、もう片方で起きます。

- 元の値を保存していないときは、触っていない項目から復元する。ただし、その項目の裏づけを、1 件ずつ目で確かめる。

- 印を「false」にするのは、消すのとは違う。列に残り続けます。

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

  2026 年 10 月 17 日の記録。

iOS アプリ「トレカダッシュ (https://koshinstudio.com/works/torecadash/)」で、「複数の商品を受け付けている抽選なのに、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 件を削除しました。

### 分かったこと

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

- 「1 ページ ＝ 1 案件」を、前提にしない。1 つのフォームで、複数の商品を受け付ける店は、普通にあります。

- 直したら、すでにある記事も見る。入口だけを直しても、隠れた記事は戻りません。

- サーバが作った項目を、アプリが読んでいるか、突き合わせる。費用だけかかって、利用者に見えない、ということが起きます。

- 言い回しの一覧より、一般的な規則。具体的な日付が入っていれば、商品名ではない、のように。

## それぞれの要点

- 「ヤマダ電機」と「ヤマダデンキ」：店名を「含んでいるか」だけで比べ、締切を 59 秒の差で別と判定し、重複整理が手動専用だった。言い換えの表は作らず一般則で直し、1 時間おきの定期実行にした。表記ゆれ 2 件、重複 7 組が 0 に。

- あいまいな店名で地図を引くと、日本の真ん中の静岡が返る：店名を Google の地図検索に渡すと、あいまいな名前では日本全体の矩形の真ん中（静岡・愛知）が返った。ヤマダデンキが浜松、サンエーが掛川の工場に。チェーン名の一覧は作らず、答え自身で信用できるかを 4 つの規則で判定した。

- 「同じ応募ページ」なら「同じ店」と決めつけていた：同じ応募ページの記事の店名を書き揃える処理が、仙台駅前店を「新宿南口店」にしていた。応募ページは 15 の別々の店が共有していた。「確かめられたときだけ揃える」に直し、52 件を、触っていない項目から復元した記録。

- 「1 ページ ＝ 1 案件」ではなかった：リンクだけで重複と決めるジョブが、1 つの Google フォームで 6 商品を受け付ける店の記事 5 件を消していた。「リンク ＋ 商品」に直した。サーバが作った「応募枠」をアプリが一度も読んでいなかったことも見つかった。

  ほかの記録は、Notes の一覧 (https://koshinstudio.com/notes/)から、テーマごとに読めます。トレカダッシュそのものは、作品ページ (https://koshinstudio.com/works/torecadash/)に書いています。
