# 검색에서 태그 동의어가 작동하지 않아요

**URL:** https://meta.discourse.org/t/tag-synonyms-not-working-in-search/362740
**Category:** Bug
**Tags:** pr-welcome, tags
**Created:** [4월 21, 2025, 1:08오전 UTC](https://meta.discourse.org/t/tag-synonyms-not-working-in-search/362740 "2025-04-21T01:08:51Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Eviepayne](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviepayne/32/352733_2.png) [@Eviepayne](https://meta.discourse.org/u/Eviepayne)
#### Post date: [4월 21, 2025, 1:08오전 UTC](https://meta.discourse.org/t/tag-synonyms-not-working-in-search/362740/1 "2025-04-21T01:08:51Z")

</div>

포럼에서 `tags:tag1`로 검색할 때, tag1이 tag-one의 동의어라면 결과가 표시되지 않고 tag-one이 포함된 게시글도 검색되지 않습니다.

---

<div class="post-metadata">

### Author: ![Eviepayne](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviepayne/32/352733_2.png) [@Eviepayne](https://meta.discourse.org/u/Eviepayne)
#### Post date: [4월 22, 2025, 1:16오후 UTC](https://meta.discourse.org/t/tag-synonyms-not-working-in-search/362740/3 "2025-04-22T13:16:25Z")

</div>

이것은 의도된 동작이 아닐 것 같아 버그로 표시하겠습니다.

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [4월 23, 2025, 5:30오전 UTC](https://meta.discourse.org/t/tag-synonyms-not-working-in-search/362740/4 "2025-04-23T05:30:23Z")

</div>

알겠습니다. 여기에서 동의어 처리를 추가해야 할 것 같네요. 동의합니다.

커뮤니티가 도움을 주길 원할 경우를 대비해 이 이슈에 #pr-welcome 태그를 달아두겠습니다. 검색 기능은 매우 독립적으로 구현되어 있어, 테스트를 작성하는 것도 아주 간단할 것입니다.

---

<div class="post-metadata">

### Author: ![Moin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/moin/32/554653_2.png) [@Moin](https://meta.discourse.org/u/Moin)
#### Post date: [2월 12, 2026, 9:32오전 UTC](https://meta.discourse.org/t/tag-synonyms-not-working-in-search/362740/5 "2026-02-12T09:32:16Z")

</div>

수정 완료 🎉

이제 다음 검색이 모두 정상적으로 작동합니다:  
[Search for tag:howto](https://meta.discourse.org/search?q=tag%3Ahowto)  
[Search for tag:how-to](https://meta.discourse.org/search?q=tag%3Ahow-to)  
[Search for #howto](https://meta.discourse.org/search?q=%23howto)  
[Search for #how-to](https://meta.discourse.org/search?q=%23how-to)

> <https://github.com/discourse/discourse/pull/37628>
>
> What is the problem?
> 
> Discourse allows admins to mark a tag as a synonym of anot…her tag. For
> example, "brunch" can be made a synonym of "lunch". When this happens,
> all topics tagged with "brunch" are automatically retagged with "lunch",
> and the \`tags.target\_tag\_id\` column on the synonym tag record is set to
> point to the target tag.
> 
> However, several code paths did not account for synonyms:
> 
> 1. \*\*Search:\*\* \`Search#search\_tags\` and the hashtag advanced filter did
> not resolve synonyms. When a user searched using a synonym name (e.g.
> \`tags:brunch\`, \`tags:brunch+eggs\`, or \`#brunch\`), no results were
> returned because:
> - The \`tags:\` comma path queries \`topic\_tags\` joined with \`tags\` by
> name, but topics are tagged with the target tag "lunch", not the
> synonym "brunch".
> - The \`tags:\` plus path aggregates tag names per topic into a
> tsvector and matches against the searched name, but the aggregated
> names are target tag names, so "brunch" never matches.
> - The \`#\` hashtag path picks the synonym tag's own \`id\` and queries
> \`topic\_tags\` by that ID, but topics store the target tag's ID.
> 
> 2. \*\*Filter route:\*\* \`TopicsFilter#tag\_ids\_from\_tag\_names\` concatenated
> both the synonym's own ID and the target tag ID. For match-all
> queries (e.g. \`tag:brunch\`), this required a topic to have both IDs
> in \`topic\_tags\`, which never happens since only the target tag ID is
> stored. For negation queries (e.g. \`-tag:brunch\`), the exclusion
> targeted the synonym ID rather than the target, so no topics were
> excluded.
> 
> What is the solution?
> 
> In \`Search#search\_tags\`, add a synonym resolution step before the
> existing comma/plus branching logic. It splits the match string into
> individual tag names, queries for any that are synonyms via
> \`Tag.where\_name(tag\_names).where.not(target\_tag\_id: nil)\`, builds a
> name mapping, and replaces synonym names with their target tag names.
> The replacement operates on the split array elements rather than using
> substring replacement to avoid corrupting tag names that may contain
> other tag names as substrings.
> 
> In the hashtag advanced filter, pick both \`:id\` and \`:target\_tag\_id\`
> from the tag lookup and prefer \`target\_tag\_id\` when present, so the
> query uses the target tag's ID instead of the synonym's own ID.
> 
> In \`TopicsFilter#tag\_ids\_from\_tag\_names\`, replace the transpose/concat
> approach with \`.map { |id, target\_id| target\_id || id }\` to resolve
> each tag to its canonical ID — the target for synonyms, or the tag's
> own ID otherwise.
> 
> A partial index on \`tags.target\_tag\_id\` is added (scoped to
> \`WHERE target\_tag\_id IS NOT NULL\`) to support efficient synonym lookups.

---

<div class="post-metadata">

### Author: ![nat](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nat/32/235063_2.png) [@nat](https://meta.discourse.org/u/nat)
#### Post date: [2월 14, 2026, 12:00오전 UTC](https://meta.discourse.org/t/tag-synonyms-not-working-in-search/362740/6 "2026-02-14T00:00:49Z")

</div>

이 주제는 38시간 후 자동으로 닫혔습니다. 더 이상 새 답글을 작성할 수 없습니다.
