倒排索引核心结构是「词→文档ID列表」映射,由Term Dictionary(排序词典,支持二分查找)、Term Index(基于FST的前缀索引,内存常驻、微秒级定位)和Posting List(文档ID及位置信息列表)三层协同构成。

倒排索引的核心结构怎么建
倒排索引本质是「词 → 文档ID列表」的映射,Go 里最直接的实现就是 map[string][]int 或 map[string]map[int]struct{}。前者适合文档量不大、频繁遍历 ID 列表的场景;后者用 map[int]struct{} 能去重且查存在性快(if _, ok := idx["go"][123]; ok),但遍历开销略高。
别用 map[string][]string 存文档路径——ID 是整数更省内存、排序/交并计算也更快。文档路径应单独用切片或 map 缓存:docsByID := []string{"./a.md", "./b.md"}。
常见错误:把分词结果直接当 key 存,没做标准化(比如大小写、标点、停用词)。结果搜 "Go" 找不到 "go"。必须统一小写 + 去标点(用 strings.Map 或正则预处理)。
分词和索引构建时要注意什么
Go 标准库没有内建中文分词,英文可简单用 strings.FieldsFunc 按空白和标点切分,但得手动过滤空串和停用词。例如:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
words := strings.FieldsFunc(text, func(r rune) bool {
return !unicode.IsLetter(r) && !unicode.IsNumber(r)
})
for i := range words {
words[i] = strings.ToLower(words[i])
}
// 过滤停用词(需提前定义 stopWords map[string]bool)
filtered := make([]string, 0, len(words))
for _, w := range words {
if !stopWords[w] && len(w) > 1 {
filtered = append(filtered, w)
}
}
中文必须引入第三方库(如 github.com/go-ego/gse),否则按字切分效果极差。注意 gse 默认启用词频,但倒排索引只关心「出现过」,设 seg.WithFrequency(false) 可省内存。
构建索引时别在循环里反复 make 新 slice——用预分配:idx[word] = append(idx[word], docID) 即可,Go 的 slice append 会自动扩容。
查询时如何高效做 AND/OR 操作
单个词查 idx["golang"] 直接返回 ID 列表。多个词 AND(求交集)推荐用双指针法,前提是 ID 列表已排序(插入时保持有序或最后 sort.Ints):
sort.SearchInts
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










