163 lines
4.7 KiB
JavaScript
163 lines
4.7 KiB
JavaScript
const items = $input.all();
|
||
const results = [];
|
||
|
||
// 通用MongoDB连接获取函数
|
||
function getMongoConnection() {
|
||
// 尝试不同的MongoDB连接变量名
|
||
if (typeof mongoClient !== 'undefined') return mongoClient;
|
||
if (typeof mongo !== 'undefined') return mongo;
|
||
if (typeof db !== 'undefined') return db;
|
||
if (typeof $mongo !== 'undefined') return $mongo;
|
||
if (typeof client !== 'undefined') return client;
|
||
|
||
throw new Error('找不到MongoDB连接对象,请检查n8n MongoDB节点配置');
|
||
}
|
||
|
||
// 改进的哈希函数 - 基于内容生成稳定的ID
|
||
function generateStableId(title, pubDate, content) {
|
||
const normalizedTitle = title.trim().toLowerCase();
|
||
const contentHash = content ? content.substring(0, 100) : '';
|
||
const dateStr = pubDate || '';
|
||
|
||
const combined = normalizedTitle + '|' + dateStr + '|' + contentHash;
|
||
|
||
let hash = 0;
|
||
for (let i = 0; i < combined.length; i++) {
|
||
const char = combined.charCodeAt(i);
|
||
hash = ((hash << 5) - hash) + char;
|
||
hash = hash & hash;
|
||
}
|
||
return Math.abs(hash).toString(16);
|
||
}
|
||
|
||
console.log(`开始处理 ${items.length} 条RSS数据`);
|
||
|
||
// 获取MongoDB连接
|
||
let mongoConnection;
|
||
try {
|
||
mongoConnection = getMongoConnection();
|
||
console.log('✅ MongoDB连接获取成功');
|
||
} catch (error) {
|
||
console.error('❌ MongoDB连接失败:', error.message);
|
||
return [{
|
||
json: {
|
||
error: 'MongoDB连接失败',
|
||
message: error.message,
|
||
status: 'connection_failed'
|
||
}
|
||
}];
|
||
}
|
||
|
||
// 用于本次执行内去重
|
||
const processedInThisRun = new Set();
|
||
|
||
// 处理每个RSS项目
|
||
for (const item of items) {
|
||
const data = item.json;
|
||
|
||
// 跳过无效数据
|
||
if (!data.title) {
|
||
console.log('跳过无标题数据');
|
||
continue;
|
||
}
|
||
|
||
// 本次执行内去重检查
|
||
if (processedInThisRun.has(data.title)) {
|
||
console.log('⏭️ 本次执行内重复,跳过:', data.title);
|
||
continue;
|
||
}
|
||
|
||
// 生成稳定的文章ID
|
||
const stableId = generateStableId(
|
||
data.title,
|
||
data.isoDate || data.pubDate,
|
||
data['content:encodedSnippet'] || data.contentSnippet || ''
|
||
);
|
||
|
||
// 生成内容哈希
|
||
const contentHash = generateStableId(
|
||
data['content:encodedSnippet'] || data.contentSnippet || '',
|
||
'',
|
||
''
|
||
);
|
||
|
||
// 准备文章数据
|
||
const articleData = {
|
||
article_id: stableId,
|
||
title: data.title,
|
||
content: data['content:encodedSnippet'] || data.contentSnippet || '',
|
||
content_hash: contentHash,
|
||
published_time: data.isoDate || data.pubDate || new Date().toISOString(),
|
||
source_url: data.link || '',
|
||
rss_source: data.meta?.title || 'unknown',
|
||
processed: false,
|
||
created_at: new Date().toISOString(),
|
||
last_updated: new Date().toISOString()
|
||
};
|
||
|
||
try {
|
||
// 检查数据库中是否已存在
|
||
const existing = await mongoConnection.db('taigong').collection('articles').findOne({
|
||
$or: [
|
||
{ article_id: stableId },
|
||
{ title: data.title }
|
||
]
|
||
});
|
||
|
||
if (existing) {
|
||
console.log('⏭️ 数据库中已存在,跳过:', data.title);
|
||
continue;
|
||
}
|
||
|
||
// 插入新文章
|
||
const result = await mongoConnection.db('taigong').collection('articles').insertOne(articleData);
|
||
|
||
console.log('✅ 新增文章:', data.title);
|
||
results.push({
|
||
json: {
|
||
action: 'inserted',
|
||
article_id: stableId,
|
||
title: data.title,
|
||
mongodb_id: result.insertedId,
|
||
status: 'success'
|
||
}
|
||
});
|
||
|
||
// 添加到本次执行的去重集合
|
||
processedInThisRun.add(data.title);
|
||
|
||
} catch (error) {
|
||
console.error('❌ 处理文章失败:', data.title, error.message);
|
||
results.push({
|
||
json: {
|
||
action: 'error',
|
||
title: data.title,
|
||
error: error.message,
|
||
status: 'failed'
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
console.log(`处理完成: 原始${items.length}条, 成功处理${results.length}条`);
|
||
|
||
// 统计结果
|
||
const stats = results.reduce((acc, item) => {
|
||
acc[item.json.action] = (acc[item.json.action] || 0) + 1;
|
||
return acc;
|
||
}, {});
|
||
|
||
console.log('处理统计:', stats);
|
||
|
||
// 如果没有任何结果,返回一个空的成功状态
|
||
if (results.length === 0) {
|
||
return [{
|
||
json: {
|
||
message: '没有新数据需要处理',
|
||
total_processed: items.length,
|
||
status: 'completed'
|
||
}
|
||
}];
|
||
}
|
||
|
||
return results; |