Files
akmon/doc_news/IMMUTABLE_ERROR_FINAL_SOLUTION.md
2026-01-20 08:04:15 +08:00

122 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# IMMUTABLE函数错误最终解决方案
## 🔧 问题解决
**错误**: `ERROR: 42P17: functions in index predicate must be marked IMMUTABLE`
**最终解决方案**: 使用简单的表达式索引完全避免自定义IMMUTABLE函数的复杂性。
## ✅ 修复内容
### 移除了复杂的IMMUTABLE函数
**之前 (复杂方案)**:
```sql
-- 创建自定义IMMUTABLE函数
CREATE FUNCTION content_title_to_tsvector(title TEXT)
RETURNS tsvector LANGUAGE sql IMMUTABLE STRICT...
-- 使用自定义函数的索引
CREATE INDEX ... USING gin(content_title_to_tsvector(title));
```
**现在 (简化方案)**:
```sql
-- 直接使用表达式索引
CREATE INDEX IF NOT EXISTS idx_contents_title_gin
ON public.ak_contents USING gin((to_tsvector('simple'::regconfig, title)));
CREATE INDEX IF NOT EXISTS idx_contents_content_gin
ON public.ak_contents USING gin((to_tsvector('simple'::regconfig, content)));
```
## 🎯 优势
1. **简单可靠**: 避免自定义函数的复杂性
2. **兼容性强**: 适用于所有PostgreSQL版本
3. **性能良好**: 表达式索引同样高效
4. **维护简单**: 不需要管理额外的函数
## 📋 使用方法
### 全文搜索查询
```sql
-- 搜索标题
SELECT id, title, published_at
FROM ak_contents
WHERE to_tsvector('simple', title) @@ to_tsquery('simple', 'AI');
-- 搜索内容
SELECT id, title, LEFT(content, 200) as preview
FROM ak_contents
WHERE to_tsvector('simple', content) @@ to_tsquery('simple', 'technology');
-- 组合搜索
SELECT id, title, published_at
FROM ak_contents
WHERE to_tsvector('simple', title) @@ to_tsquery('simple', 'AI | machine')
OR to_tsvector('simple', content) @@ to_tsquery('simple', 'AI | machine')
ORDER BY published_at DESC;
-- 相关性排序
SELECT id, title,
ts_rank(to_tsvector('simple', title), query) +
ts_rank(to_tsvector('simple', content), query) as rank
FROM ak_contents, to_tsquery('simple', 'artificial & intelligence') query
WHERE to_tsvector('simple', title) @@ query
OR to_tsvector('simple', content) @@ query
ORDER BY rank DESC;
```
### 高级搜索功能
```sql
-- 短语搜索
SELECT * FROM ak_contents
WHERE to_tsvector('simple', title) @@ phraseto_tsquery('simple', 'artificial intelligence');
-- 自然语言搜索
SELECT * FROM ak_contents
WHERE to_tsvector('simple', content) @@ plainto_tsquery('simple', 'machine learning algorithms');
-- 搜索高亮
SELECT id, title,
ts_headline('simple', content, to_tsquery('simple', 'AI'),
'MaxWords=35, MinWords=15, ShortWord=3, HighlightAll=FALSE') as highlight
FROM ak_contents
WHERE to_tsvector('simple', content) @@ to_tsquery('simple', 'AI');
```
## 🚀 部署状态
**状态**: ✅ 问题完全解决
- ✅ 移除了有问题的IMMUTABLE函数
- ✅ 使用简单可靠的表达式索引
- ✅ 保持高性能全文搜索功能
- ✅ 支持所有PostgreSQL/Supabase版本
## 📝 升级说明
如果您之前部署过有IMMUTABLE函数的版本
1. **自动清理**: 新版本会自动删除旧的索引
2. **重新创建**: 自动创建新的简化索引
3. **查询兼容**: 查询方式略有变化,请参考上面的示例
## 🎉 结论
通过使用简单的表达式索引而不是自定义IMMUTABLE函数我们彻底解决了 `ERROR: 42P17` 错误,同时保持了优秀的全文搜索性能。
这个解决方案更加:
- 🔧 **简单**: 无需维护自定义函数
- 🛡️ **可靠**: 避免版本兼容性问题
-**高效**: 查询性能依然优秀
- 🌐 **通用**: 适用于所有环境
---
**修复时间**: 2025年6月18日
**问题状态**: ✅ 已完全解决
**兼容性**: 全版本PostgreSQL/Supabase