镜像自地址
https://github.com/lhly/search-syntax-pro.git
已同步 2026-10-21 06:41:51 +08:00
- 添加 DuckDuckGo、Brave、Yandex、Reddit、GitHub 和 StackOverflow 适配器 - 实现动态语言选择器功能 - 更新搜索引擎类型定义和国际化翻译 - 添加详细的搜索引擎文档和语法参考
675 行
14 KiB
Markdown
675 行
14 KiB
Markdown
# Reddit 搜索引擎适配器文档
|
||
|
||
## 📋 基本信息
|
||
|
||
| 属性 | 值 |
|
||
|------|-----|
|
||
| **引擎名称** | Reddit |
|
||
| **官方网站** | https://www.reddit.com |
|
||
| **市场定位** | 社区内容搜索平台 |
|
||
| **月活用户** | 4.3亿+ |
|
||
| **日帖子量** | 200万+ |
|
||
| **主要用户群** | 社区用户、研究者、营销人员、开发者 |
|
||
| **优先级** | **P1 (中等)** |
|
||
| **实施复杂度** | 🟡 中等 |
|
||
| **预计工期** | 2-3天 |
|
||
|
||
## 🎯 产品价值
|
||
|
||
### 用户价值
|
||
- ✅ **社区洞察**: 获取真实用户讨论和观点
|
||
- ✅ **趋势发现**: 了解热门话题和社区动态
|
||
- ✅ **专业内容**: 访问各领域专家的讨论
|
||
- ✅ **UGC搜索**: 用户生成内容的精准搜索
|
||
|
||
### 业务价值
|
||
- 📊 市场研究和用户调研工具
|
||
- 🎯 垂直搜索差异化
|
||
- 💼 营销和社交媒体分析
|
||
- 🔍 内容发现和灵感来源
|
||
|
||
## 🔍 支持的搜索语法
|
||
|
||
### 1. 基础语法
|
||
|
||
#### 1.1 关键词搜索
|
||
```
|
||
关键词
|
||
```
|
||
|
||
**示例**:
|
||
```
|
||
Python tutorial
|
||
React best practices
|
||
```
|
||
|
||
**说明**: 搜索标题和正文中包含关键词的帖子
|
||
|
||
---
|
||
|
||
#### 1.2 精确匹配 (`"..."`)
|
||
```
|
||
"完整短语"
|
||
```
|
||
|
||
**示例**:
|
||
```
|
||
"how to learn React"
|
||
"best programming languages"
|
||
```
|
||
|
||
**说明**: 搜索包含完整短语的帖子
|
||
|
||
---
|
||
|
||
#### 1.3 排除关键词 (`-` 或 `NOT`)
|
||
```
|
||
关键词 -排除词
|
||
关键词 NOT 排除词
|
||
```
|
||
|
||
**示例**:
|
||
```
|
||
Python -Django
|
||
React NOT class
|
||
```
|
||
|
||
**说明**: 排除包含指定词的结果
|
||
|
||
---
|
||
|
||
### 2. 筛选器语法
|
||
|
||
#### 2.1 Subreddit 筛选 (`subreddit:`)
|
||
```
|
||
关键词 subreddit:社区名
|
||
```
|
||
|
||
**示例**:
|
||
```
|
||
tutorial subreddit:learnprogramming
|
||
news subreddit:technology
|
||
```
|
||
|
||
**说明**: 只搜索特定subreddit中的内容
|
||
|
||
---
|
||
|
||
#### 2.2 作者筛选 (`author:`)
|
||
```
|
||
关键词 author:用户名
|
||
```
|
||
|
||
**示例**:
|
||
```
|
||
tutorial author:spez
|
||
Python author:guido
|
||
```
|
||
|
||
**说明**: 只搜索特定用户发布的帖子
|
||
|
||
---
|
||
|
||
#### 2.3 URL筛选 (`url:`)
|
||
```
|
||
url:网址关键词
|
||
```
|
||
|
||
**示例**:
|
||
```
|
||
url:github.com
|
||
url:youtube
|
||
```
|
||
|
||
**说明**: 搜索链接到特定URL的帖子
|
||
|
||
---
|
||
|
||
#### 2.4 标题搜索 (`title:`)
|
||
```
|
||
title:关键词
|
||
```
|
||
|
||
**示例**:
|
||
```
|
||
title:tutorial
|
||
title:"best practices"
|
||
```
|
||
|
||
**说明**: 只搜索标题中包含关键词的帖子
|
||
|
||
---
|
||
|
||
#### 2.5 正文搜索 (`selftext:`)
|
||
```
|
||
selftext:关键词
|
||
```
|
||
|
||
**示例**:
|
||
```
|
||
selftext:tutorial
|
||
selftext:"step by step"
|
||
```
|
||
|
||
**说明**: 只搜索正文内容(文本帖子的正文)
|
||
|
||
---
|
||
|
||
#### 2.6 帖子类型筛选 (`self:`)
|
||
```
|
||
self:yes # 只显示文本帖子
|
||
self:no # 只显示链接帖子
|
||
```
|
||
|
||
**示例**:
|
||
```
|
||
Python tutorial self:yes
|
||
news self:no
|
||
```
|
||
|
||
**说明**:
|
||
- `self:yes` - 只显示自发文本帖子
|
||
- `self:no` - 只显示外部链接帖子
|
||
|
||
---
|
||
|
||
### 3. 逻辑运算符
|
||
|
||
#### 3.1 OR 逻辑
|
||
```
|
||
关键词1 OR 关键词2
|
||
```
|
||
|
||
**示例**:
|
||
```
|
||
Python OR JavaScript
|
||
React OR Vue
|
||
```
|
||
|
||
**说明**: 搜索包含任一关键词的帖子(OR必须大写)
|
||
|
||
---
|
||
|
||
#### 3.2 AND 逻辑 (默认)
|
||
```
|
||
关键词1 关键词2
|
||
```
|
||
|
||
**示例**:
|
||
```
|
||
Python tutorial beginner
|
||
```
|
||
|
||
**说明**: 默认所有关键词都必须出现
|
||
|
||
---
|
||
|
||
### 4. 时间筛选
|
||
|
||
Reddit搜索支持时间范围筛选,但主要通过UI进行:
|
||
|
||
| 时间范围 | 参数值 | 说明 |
|
||
|---------|-------|------|
|
||
| 过去1小时 | `hour` | 最近1小时的内容 |
|
||
| 过去24小时 | `day` | 今天的内容 |
|
||
| 过去1周 | `week` | 本周的内容 |
|
||
| 过去1月 | `month` | 本月的内容 |
|
||
| 过去1年 | `year` | 今年的内容 |
|
||
| 所有时间 | `all` | 不限时间 |
|
||
|
||
**URL参数**: `t=day|week|month|year|all`
|
||
|
||
---
|
||
|
||
### 5. 排序方式
|
||
|
||
| 排序方式 | 参数值 | 说明 |
|
||
|---------|-------|------|
|
||
| 相关性 | `relevance` | 默认排序 |
|
||
| 热门 | `hot` | 最热门的帖子 |
|
||
| 最新 | `new` | 最新发布的 |
|
||
| 评论数 | `comments` | 评论最多的 |
|
||
| 得分 | `top` | 得分最高的 |
|
||
|
||
**URL参数**: `sort=relevance|hot|new|comments|top`
|
||
|
||
---
|
||
|
||
## 🔧 技术实现
|
||
|
||
### URL 构建格式
|
||
|
||
**基础URL**:
|
||
```
|
||
https://www.reddit.com/search
|
||
```
|
||
|
||
**查询参数**:
|
||
```typescript
|
||
interface RedditSearchParams {
|
||
q: string; // 搜索查询
|
||
sort?: string; // 排序: relevance|hot|new|comments|top
|
||
t?: string; // 时间范围: hour|day|week|month|year|all
|
||
type?: string; // 搜索类型: link|sr (默认link)
|
||
restrict_sr?: boolean; // 限制在当前subreddit
|
||
}
|
||
```
|
||
|
||
**完整URL示例**:
|
||
```
|
||
https://www.reddit.com/search/?q=Python+tutorial+subreddit%3Alearnprogramming&sort=relevance&t=all
|
||
```
|
||
|
||
### 适配器实现模板
|
||
|
||
```typescript
|
||
import type { SearchEngineAdapter, SearchParams, SyntaxType, ValidationResult, UIFeatureType } from '@/types'
|
||
|
||
/**
|
||
* Reddit 搜索引擎适配器
|
||
* 支持社区内容搜索和用户生成内容发现
|
||
*/
|
||
export class RedditAdapter implements SearchEngineAdapter {
|
||
getName(): string {
|
||
return 'Reddit'
|
||
}
|
||
|
||
getBaseUrl(): string {
|
||
return 'https://www.reddit.com/search/'
|
||
}
|
||
|
||
/**
|
||
* 构建 Reddit 搜索查询 URL
|
||
*/
|
||
buildQuery(params: SearchParams): string {
|
||
const baseUrl = this.getBaseUrl()
|
||
const query = this.buildSearchQuery(params)
|
||
|
||
const urlParams = new URLSearchParams({
|
||
q: query,
|
||
sort: 'relevance',
|
||
t: 'all'
|
||
})
|
||
|
||
return `${baseUrl}?${urlParams.toString()}`
|
||
}
|
||
|
||
/**
|
||
* 构建搜索查询字符串
|
||
*/
|
||
private buildSearchQuery(params: SearchParams): string {
|
||
const queryParts: string[] = []
|
||
|
||
// 1. 基础关键词
|
||
if (params.keyword && params.keyword.trim()) {
|
||
queryParts.push(params.keyword.trim())
|
||
}
|
||
|
||
// 2. 精确匹配
|
||
if (params.exactMatch && params.exactMatch.trim()) {
|
||
queryParts.push(`"${params.exactMatch.trim()}"`)
|
||
}
|
||
|
||
// 3. Subreddit筛选 (使用site作为subreddit)
|
||
if (params.site && params.site.trim()) {
|
||
queryParts.push(`subreddit:${params.site.trim()}`)
|
||
}
|
||
|
||
// 4. 作者筛选 (使用fromUser作为author)
|
||
if (params.fromUser && params.fromUser.trim()) {
|
||
const author = params.fromUser.replace('@', '')
|
||
queryParts.push(`author:${author}`)
|
||
}
|
||
|
||
// 5. URL筛选
|
||
if (params.inUrl && params.inUrl.trim()) {
|
||
queryParts.push(`url:${params.inUrl.trim()}`)
|
||
}
|
||
|
||
// 6. 标题搜索
|
||
if (params.inTitle && params.inTitle.trim()) {
|
||
queryParts.push(`title:${params.inTitle.trim()}`)
|
||
}
|
||
|
||
// 7. 正文搜索
|
||
if (params.inText && params.inText.trim()) {
|
||
queryParts.push(`selftext:${params.inText.trim()}`)
|
||
}
|
||
|
||
// 8. 排除关键词
|
||
if (params.excludeWords && params.excludeWords.length > 0) {
|
||
params.excludeWords.forEach(word => {
|
||
if (word.trim()) {
|
||
queryParts.push(`-${word.trim()}`)
|
||
}
|
||
})
|
||
}
|
||
|
||
// 9. OR 逻辑关键词
|
||
if (params.orKeywords && params.orKeywords.length > 0) {
|
||
const orQuery = params.orKeywords
|
||
.filter(word => word.trim())
|
||
.join(' OR ')
|
||
if (orQuery) {
|
||
queryParts.push(`(${orQuery})`)
|
||
}
|
||
}
|
||
|
||
return queryParts.join(' ')
|
||
}
|
||
|
||
/**
|
||
* 验证语法类型
|
||
*/
|
||
validateSyntax(syntax: SyntaxType): boolean {
|
||
const supportedSyntax: SyntaxType[] = [
|
||
'site', // 映射为 subreddit:
|
||
'exact',
|
||
'intitle',
|
||
'inurl',
|
||
'intext',
|
||
'exclude',
|
||
'or',
|
||
'from_user' // 映射为 author:
|
||
]
|
||
return supportedSyntax.includes(syntax)
|
||
}
|
||
|
||
/**
|
||
* 获取支持的语法类型
|
||
*/
|
||
getSupportedSyntax(): SyntaxType[] {
|
||
return [
|
||
'site',
|
||
'exact',
|
||
'intitle',
|
||
'inurl',
|
||
'intext',
|
||
'exclude',
|
||
'or',
|
||
'from_user'
|
||
]
|
||
}
|
||
|
||
/**
|
||
* 获取支持的UI功能特性
|
||
*/
|
||
getSupportedFeatures(): UIFeatureType[] {
|
||
return [
|
||
'site', // 显示为"Subreddit"
|
||
'exact_match',
|
||
'intitle',
|
||
'inurl',
|
||
'intext',
|
||
'exclude',
|
||
'or_keywords',
|
||
'from_user' // 显示为"作者"
|
||
]
|
||
}
|
||
|
||
/**
|
||
* 验证搜索参数
|
||
*/
|
||
validateParams(params: SearchParams): ValidationResult {
|
||
const errors: string[] = []
|
||
const warnings: string[] = []
|
||
|
||
// 检查基本关键词
|
||
if (!params.keyword || !params.keyword.trim()) {
|
||
if (!params.exactMatch && !params.site && !params.fromUser) {
|
||
errors.push('请输入搜索关键词')
|
||
}
|
||
}
|
||
|
||
// 检查subreddit名称
|
||
if (params.site && params.site.trim()) {
|
||
const subredditPattern = /^[a-zA-Z0-9_]{3,21}$/
|
||
if (!subredditPattern.test(params.site.trim())) {
|
||
warnings.push('Subreddit名称格式可能不正确')
|
||
}
|
||
}
|
||
|
||
// 检查用户名
|
||
if (params.fromUser && params.fromUser.trim()) {
|
||
const username = params.fromUser.replace('@', '')
|
||
const usernamePattern = /^[a-zA-Z0-9_-]{3,20}$/
|
||
if (!usernamePattern.test(username)) {
|
||
warnings.push('用户名格式可能不正确')
|
||
}
|
||
}
|
||
|
||
return {
|
||
isValid: errors.length === 0,
|
||
errors,
|
||
warnings
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取搜索建议
|
||
*/
|
||
getSearchSuggestions(params: SearchParams): string[] {
|
||
const suggestions: string[] = []
|
||
|
||
if (params.keyword && !params.site) {
|
||
suggestions.push('尝试添加 subreddit: 限定搜索社区')
|
||
}
|
||
|
||
if (params.keyword && !params.fromUser) {
|
||
suggestions.push('使用 author: 可以搜索特定用户的帖子')
|
||
}
|
||
|
||
if (!params.exactMatch) {
|
||
suggestions.push('使用精确匹配可以找到更准确的讨论')
|
||
}
|
||
|
||
return suggestions
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 📝 实施清单
|
||
|
||
### Phase 1: 核心功能 (Day 1)
|
||
- [ ] 创建 `src/services/adapters/reddit.ts`
|
||
- [ ] 实现 `RedditAdapter` 类
|
||
- [ ] 实现基础语法 (关键词、精确匹配)
|
||
- [ ] 单元测试
|
||
|
||
### Phase 2: 筛选器 (Day 2)
|
||
- [ ] 实现 subreddit: 筛选
|
||
- [ ] 实现 author: 筛选
|
||
- [ ] 实现 url:, title:, selftext: 筛选
|
||
- [ ] 参数验证
|
||
|
||
### Phase 3: UI集成 (Day 3)
|
||
- [ ] 字段映射配置 (site → subreddit, fromUser → author)
|
||
- [ ] 时间范围和排序UI
|
||
- [ ] 国际化翻译
|
||
- [ ] 完整测试
|
||
|
||
---
|
||
|
||
## ✅ 测试用例
|
||
|
||
```typescript
|
||
describe('RedditAdapter', () => {
|
||
const adapter = new RedditAdapter()
|
||
|
||
test('基础关键词搜索', () => {
|
||
const url = adapter.buildQuery({
|
||
keyword: 'Python tutorial',
|
||
engine: 'reddit'
|
||
})
|
||
expect(url).toContain('q=Python+tutorial')
|
||
expect(url).toContain('sort=relevance')
|
||
})
|
||
|
||
test('Subreddit筛选', () => {
|
||
const url = adapter.buildQuery({
|
||
keyword: 'tutorial',
|
||
site: 'learnprogramming',
|
||
engine: 'reddit'
|
||
})
|
||
expect(url).toContain('subreddit%3Alearnprogramming')
|
||
})
|
||
|
||
test('作者筛选', () => {
|
||
const url = adapter.buildQuery({
|
||
keyword: 'announcement',
|
||
fromUser: 'spez',
|
||
engine: 'reddit'
|
||
})
|
||
expect(url).toContain('author%3Aspez')
|
||
})
|
||
|
||
test('标题和正文搜索', () => {
|
||
const url = adapter.buildQuery({
|
||
keyword: 'React',
|
||
inTitle: 'tutorial',
|
||
inText: 'beginner',
|
||
engine: 'reddit'
|
||
})
|
||
expect(url).toContain('title%3Atutorial')
|
||
expect(url).toContain('selftext%3Abeginner')
|
||
})
|
||
|
||
test('OR逻辑', () => {
|
||
const url = adapter.buildQuery({
|
||
keyword: 'tutorial',
|
||
orKeywords: ['Python', 'JavaScript'],
|
||
engine: 'reddit'
|
||
})
|
||
expect(url).toContain('Python+OR+JavaScript')
|
||
})
|
||
|
||
test('组合查询', () => {
|
||
const url = adapter.buildQuery({
|
||
keyword: 'tutorial',
|
||
site: 'programming',
|
||
fromUser: 'expert',
|
||
excludeWords: ['beginner'],
|
||
engine: 'reddit'
|
||
})
|
||
expect(url).toContain('subreddit%3Aprogramming')
|
||
expect(url).toContain('author%3Aexpert')
|
||
expect(url).toContain('-beginner')
|
||
})
|
||
})
|
||
```
|
||
|
||
---
|
||
|
||
## 🌍 国际化支持
|
||
|
||
```json
|
||
{
|
||
"engines.reddit": "Reddit",
|
||
"engines.reddit.description": "全球最大社区内容搜索平台",
|
||
"engines.reddit.features": {
|
||
"subreddit": "Subreddit社区",
|
||
"author": "作者筛选",
|
||
"selftext": "正文搜索",
|
||
"title": "标题搜索",
|
||
"url": "链接筛选"
|
||
},
|
||
"engines.reddit.labels": {
|
||
"site": "Subreddit",
|
||
"fromUser": "作者 (Reddit用户名)",
|
||
"timeRange": "时间范围",
|
||
"sortBy": "排序方式"
|
||
},
|
||
"engines.reddit.tips": {
|
||
"subreddit": "输入subreddit名称(不含r/前缀)",
|
||
"author": "输入Reddit用户名(不含u/前缀)",
|
||
"selftext": "搜索文本帖子的正文内容"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🎨 UI特殊处理
|
||
|
||
### 字段映射
|
||
|
||
Reddit使用特殊的术语,需要在UI层进行映射:
|
||
|
||
| 通用字段 | Reddit术语 | 说明 |
|
||
|---------|-----------|------|
|
||
| `site` | `subreddit` | 社区名称 |
|
||
| `fromUser` | `author` | 用户名 |
|
||
| `inText` | `selftext` | 正文内容 |
|
||
|
||
### UI标签建议
|
||
|
||
```typescript
|
||
// UI组件中的特殊处理
|
||
const getFieldLabel = (field: string, engine: SearchEngine) => {
|
||
if (engine === 'reddit') {
|
||
const redditLabels = {
|
||
site: 'Subreddit',
|
||
fromUser: 'Reddit用户',
|
||
inText: '帖子正文'
|
||
}
|
||
return redditLabels[field] || field
|
||
}
|
||
return field
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 📚 参考资源
|
||
|
||
### 官方文档
|
||
- [Reddit Search Documentation](https://www.reddit.com/wiki/search/)
|
||
- [Reddit API Documentation](https://www.reddit.com/dev/api/)
|
||
- [Advanced Reddit Search Guide](https://upvoteshop.io/advanced-reddit-search-guide/)
|
||
|
||
### 技术文章
|
||
- [Reddit Search Operators](https://medium.com/@nammooo/reddit-advance-search-operators-and-filters-310206356be1)
|
||
- [How to Search Reddit Like a Pro](https://redditschedule.com/how-to-use-reddit-search-like-a-pro-to-find-anything-in-2025/)
|
||
|
||
---
|
||
|
||
## 💡 使用场景
|
||
|
||
### 1. 市场研究
|
||
```
|
||
产品名称 subreddit:产品类别
|
||
用户反馈 subreddit:reviews
|
||
```
|
||
|
||
### 2. 技术学习
|
||
```
|
||
教程 subreddit:learnprogramming
|
||
最佳实践 subreddit:programming
|
||
```
|
||
|
||
### 3. 趋势发现
|
||
```
|
||
热门话题 sort:hot t:week
|
||
讨论度高 sort:comments t:day
|
||
```
|
||
|
||
### 4. 专家观点
|
||
```
|
||
技术话题 author:知名专家
|
||
行业分析 subreddit:行业社区
|
||
```
|
||
|
||
---
|
||
|
||
## 🔄 更新日志
|
||
|
||
| 日期 | 版本 | 更新内容 |
|
||
|------|------|---------|
|
||
| 2025-11-09 | v1.0 | 初始文档创建,包含社区搜索语法 |
|
||
|
||
---
|
||
|
||
**下一步**: 查看 [GitHub 文档](./github.md) 了解代码搜索引擎的实现细节
|