This is an automated email from the ASF dual-hosted git repository.
jeffreyh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris-website.git
The following commit(s) were added to refs/heads/master by this push:
new 97acac53344 [Fix]: Redirect some links (#2971)
97acac53344 is described below
commit 97acac53344a07789433b25bfcb83416f021a471
Author: yangon <[email protected]>
AuthorDate: Tue Oct 14 15:46:09 2025 +0800
[Fix]: Redirect some links (#2971)
---
docusaurus.config.js | 9 +-
scripts/extractExternalLinks.js | 57 +++++++
src/theme/BlogPostItem/blog.data.ts | 288 ++++++++++++++++++++++++++++++++++++
src/theme/BlogPostItem/index.tsx | 15 +-
4 files changed, 362 insertions(+), 7 deletions(-)
diff --git a/docusaurus.config.js b/docusaurus.config.js
index 0a2a9f67f1a..70238b16bf2 100644
--- a/docusaurus.config.js
+++ b/docusaurus.config.js
@@ -122,22 +122,19 @@ const config = {
{
from: '/docs/dev/get-starting/',
to:
`/docs/${DEFAULT_VERSION}/gettingStarted/quick-start`,
- },
+ }
],
createRedirects(existingPath) {
- if
(existingPath.includes('/gettingStarted/what-is-apache-doris')) {
+ if
(existingPath.includes('/gettingStarted/what-is-apache-doris') ||
existingPath.startsWith('/docs/3.x/')) {
// Redirect from /gettingStarted/what-is-new to
/gettingStarted/what-is-apache-doris
return [
existingPath.replace(
'/gettingStarted/what-is-apache-doris',
'/gettingStarted/what-is-new',
),
+ existingPath.replace('/docs/3.x/', '/docs/'),
existingPath.replace('/docs/3.x/', '/docs/3.0/')
];
}
- if (existingPath.startsWith('/docs/3.x/')) {
- return [existingPath.replace('/docs/3.x/', '/docs/'),
existingPath.replace('/docs/3.x/', '/docs/3.0/')];
- }
-
return undefined; // Return a falsy value: no redirect
created
},
},
diff --git a/scripts/extractExternalLinks.js b/scripts/extractExternalLinks.js
new file mode 100644
index 00000000000..446577f99bc
--- /dev/null
+++ b/scripts/extractExternalLinks.js
@@ -0,0 +1,57 @@
+const fs = require('fs');
+const path = require('path');
+
+// Traverse all md files in the directory
+function getAllMarkdownFiles(dir) {
+ let results = [];
+ const files = fs.readdirSync(dir);
+
+ for (const file of files) {
+ const filePath = path.join(dir, file);
+ const stat = fs.statSync(filePath);
+
+ if (stat.isDirectory()) {
+ results = results.concat(getAllMarkdownFiles(filePath));
+ } else if (file.endsWith('.md')) {
+ results.push(filePath);
+ }
+ }
+
+ return results;
+}
+
+// Extract the externalLink of frontMatter
+function extractExternalLink(filePath) {
+ const content = fs.readFileSync(filePath, 'utf-8');
+ const frontMatterMatch = content.match(/^---\s*([\s\S]*?)\s*---/);
+
+ if (!frontMatterMatch) return null;
+
+ const frontMatter = frontMatterMatch[1];
+
+ // Try to resolve externalLink
+ const linkMatch =
frontMatter.match(/['"]externalLink['"]\s*:\s*['"]([^'"]+)['"]/);
+
+ if (!linkMatch) return null;
+
+ return linkMatch[1];
+}
+
+function main() {
+ const blogDir = path.join(__dirname, '../blog');
+ const mdFiles = getAllMarkdownFiles(blogDir);
+
+ const result = [];
+
+ for (const file of mdFiles) {
+ const externalLink = extractExternalLink(file);
+ if (externalLink) {
+ const relativePath = '/blog/' + path.basename(file, '.md');
+ result.push({ path: relativePath, externalLink });
+ }
+ }
+
+ console.log(JSON.stringify(result, null, 2));
+}
+
+main();
diff --git a/src/theme/BlogPostItem/blog.data.ts
b/src/theme/BlogPostItem/blog.data.ts
new file mode 100644
index 00000000000..98690aa3628
--- /dev/null
+++ b/src/theme/BlogPostItem/blog.data.ts
@@ -0,0 +1,288 @@
+export const BLOG_RELATED_EXTERNAL_LINK = [
+ {
+ path: '/blog/1-billion-json-records-1-second-query-response',
+ externalLink: 'https://www.velodb.io/blog/1422',
+ },
+ {
+ path:
'/blog/Auto-Synchronization-of-an-Entire-MySQL-Database-for-Data-Analysis',
+ externalLink: 'https://www.velodb.io/blog/135',
+ },
+ {
+ path:
'/blog/Choosing-an-OLAP-Engine-for-Financial-Risk-Management-What-to-Consider',
+ externalLink: 'https://www.velodb.io/blog/136',
+ },
+ {
+ path:
'/blog/Database-in-Fintech-How-to-Support-ten-thousand-Dashboards-Without-Causing-a-Mess',
+ externalLink: 'https://www.velodb.io/blog/133',
+ },
+ {
+ path:
'/blog/Log-Analysis-How-to-Digest-15-Billion-Logs-Per-Day-and-Keep-Big-Queries-Within-1-Second',
+ externalLink: 'https://www.velodb.io/blog/137',
+ },
+ {
+ path:
'/blog/Replacing-Apache-Hive-Elasticsearch-and-PostgreSQL-with-Apache-Doris',
+ externalLink: 'https://www.velodb.io/blog/1372',
+ },
+ {
+ path: '/blog/Tencent-LLM',
+ externalLink: 'https://www.velodb.io/blog/131',
+ },
+ {
+ path:
'/blog/a-fast-secure-high-available-real-time-data-warehouse-based-on-apache-doris',
+ externalLink: 'https://www.velodb.io/blog/155',
+ },
+ {
+ path:
'/blog/a-financial-anti-fraud-solution-based-on-the-apache-doris-data-warehouse',
+ externalLink: 'https://www.velodb.io/blog/165',
+ },
+ {
+ path:
'/blog/ai-unicorn-minimax-from-loki-and-built-a-pb-scale-logging-system-with-doris',
+ externalLink: 'https://www.velodb.io/blog/883',
+ },
+ {
+ path: '/blog/apache-doris-and-deepseek-community-voice',
+ externalLink:
+
'https://medium.com/%40xudarren1023/apache-doris-and-deepseek-redefining-intelligent-data-analytics-2b6b778e1034',
+ },
+ {
+ path:
'/blog/apache-doris-and-iceberg-building-hyperscale-data-lakehouse',
+ externalLink: 'https://www.velodb.io/blog/1450',
+ },
+ {
+ path:
'/blog/apache-doris-empowered-5G-fully-connected-factory-with-a-unified-real-time-data-platform',
+ externalLink: 'https://www.velodb.io/blog/1446',
+ },
+ {
+ path:
'/blog/apache-doris-for-log-and-time-series-data-analysis-in-netease',
+ externalLink: 'https://www.velodb.io/blog/437',
+ },
+ {
+ path:
'/blog/apache-doris-speeds-up-data-reporting-tagging-and-data-lake-analytics',
+ externalLink: 'https://www.velodb.io/blog/152',
+ },
+ {
+ path: '/blog/apache-doris-the-data-lakehouse-evolution',
+ externalLink: 'https://www.velodb.io/blog/1411',
+ },
+ {
+ path: '/blog/apache-doris-vs-rockset',
+ externalLink: 'https://www.velodb.io/blog/567',
+ },
+ {
+ path:
'/blog/arrow-flight-sql-in-apache-doris-for-10x-faster-data-transfer',
+ externalLink: 'https://www.velodb.io/blog/295',
+ },
+ {
+ path: '/blog/auto-increment-columns-in-databases',
+ externalLink: 'https://www.velodb.io/blog/252',
+ },
+ {
+ path: '/blog/auto-partition-in-apache-doris',
+ externalLink: 'https://www.velodb.io/blog/882',
+ },
+ {
+ path: '/blog/breaking-down-data-silos-with-an-apache-doris-based-cdp',
+ externalLink: 'https://www.velodb.io/blog/172',
+ },
+ {
+ path: '/blog/building-real-time-lakehouse-with-apache-doris',
+ externalLink: 'https://www.velodb.io/blog/1428',
+ },
+ {
+ path: '/blog/coffeebench-olap-showdown-part1-250829',
+ externalLink: 'https://www.velodb.io/blog/1463',
+ },
+ {
+ path: '/blog/coffeebench-part2-250917',
+ externalLink: 'https://www.velodb.io/blog/1504',
+ },
+ {
+ path:
'/blog/community-voice-2025-how-do-you-choose-between-doris-and-clickhouse',
+ externalLink:
+
'https://medium.com/@ith321.vip/its-2025-how-do-you-choose-between-doris-and-clickhouse-7d98456d9199',
+ },
+ {
+ path:
'/blog/community-voice-cut-costs-and-boost-efficiency-how-doriss-unified-lakehouse-breaks-down-data-silos',
+ externalLink:
+
'https://medium.com/@hhj19075/cut-costs-and-boost-efficiency-how-doriss-unified-lakehouse-breaks-down-data-silos-bfb1c9cd079a',
+ },
+ {
+ path:
'/blog/community-voice-doris-breaking-down-the-barriers-of-sql-dialects-and-building-a-unified-data-query-ecosystem',
+ externalLink:
+
'https://dev.to/darren_xu/doris-breaking-down-the-barriers-of-sql-dialects-and-building-a-unified-data-query-ecosystem-37k1',
+ },
+ {
+ path: '/blog/community-voice-doris-lakehouse-integration',
+ externalLink: 'https://dzone.com/articles/doris-lakehouse-integration',
+ },
+ {
+ path:
'/blog/community-voice-lakehouse-manus-mcp-lets-talk-about-lakehouse',
+ externalLink:
'https://dzone.com/articles/lakehouse-manus-mcp-lets-talk-about-lakehouse',
+ },
+ {
+ path:
'/blog/community-voice-lakehouse-starting-with-apache-doris-s3-tables',
+ externalLink:
+
'https://medium.com/@morningman.cmy/lakehousewbd-1-starting-with-apache-doris-s3-tables-10c98ae39fe1',
+ },
+ {
+ path: '/blog/community-voice-when-doris-meets-iceberg',
+ externalLink: 'https://dzone.com/articles/when-doris-meets-iceberg',
+ },
+ {
+ path: '/blog/cross-cluster-replication-for-read-write',
+ externalLink: 'https://www.velodb.io/blog/339',
+ },
+ {
+ path:
'/blog/data-analysis-for-live-streaming-what-happens-in-real-time-is-analyzed-in-real-time',
+ externalLink: 'https://www.velodb.io/blog/139',
+ },
+ {
+ path: '/blog/data-pruning-250908',
+ externalLink: 'https://www.velodb.io/blog/1489',
+ },
+ {
+ path: '/blog/data-trait-250905',
+ externalLink: 'https://www.velodb.io/blog/1488',
+ },
+ {
+ path: '/blog/doris-compute-storage-decoupled',
+ externalLink: 'https://www.velodb.io/blog/1384',
+ },
+ {
+ path: '/blog/doris-introduction-community-voice',
+ externalLink: 'https://www.baeldung.com/sql/apache-doris-tutorial',
+ },
+ {
+ path: '/blog/elasticsearch-vs-apache-doris-community-voice',
+ externalLink:
+
'https://www.linkedin.com/posts/rahul-kolluri-352447191_rethinking-elasticsearch-for-analytics-activity-7333804955700473859-2-e4?utm_source=share&utm_medium=member_desktop&rcm=ACoAACoH8OcBYW4CFSr632eidBaUEb5u1O2r30o',
+ },
+ {
+ path: '/blog/emqx-apache-doris-ecosystem-for-iot-analytics',
+ externalLink: '1-billion-json-records-1-second-query-response',
+ },
+ {
+ path: '/blog/evolution-of-the-apache-doris-execution-engine',
+ externalLink: 'https://www.velodb.io/blog/573',
+ },
+ {
+ path: '/blog/from-clickhouse-to-doris-trillion-log-scale-analytics',
+ externalLink: 'https://www.velodb.io/blog/1429',
+ },
+ {
+ path: '/blog/from-elasticsearch-to-doris-boosting-queries-by-56x',
+ externalLink: 'https://www.velodb.io/blog/1427',
+ },
+ {
+ path:
'/blog/from-presto-trino-clickhouse-and-hive-to-apache-doris-sql-convertor-for-easy-migration',
+ externalLink: 'https://www.velodb.io/blog/377',
+ },
+ {
+ path:
'/blog/from-snowflake-to-apache-doris-real-time-analytics-with-80-percentage-cost-savings',
+ externalLink: 'https://www.velodb.io/blog/1435',
+ },
+ {
+ path:
'/blog/how-big-data-is-saving-lives-in-real-time-iov-data-analytics-helps-prevent-accidents',
+ externalLink: 'https://www.velodb.io/blog/141',
+ },
+ {
+ path:
'/blog/introduction-to-apache-doris-a-next-generation-real-time-data-warehouse',
+ externalLink: 'https://www.velodb.io/blog/127',
+ },
+ {
+ path:
'/blog/inverted-index-accelerates-text-searches-by-40-time-apache-doris',
+ externalLink: 'https://www.velodb.io/blog/163',
+ },
+ {
+ path: '/blog/job-scheduler-for-task-automation',
+ externalLink: 'https://www.velodb.io/blog/574',
+ },
+ {
+ path:
'/blog/kwai-replace-clickhouse-with-apache-doris-for-unified-lakehouse',
+ externalLink: 'https://www.velodb.io/blog/1432',
+ },
+ {
+ path:
'/blog/leading-ai-company-revamped-observability-with-apache-doris',
+ externalLink: 'https://www.velodb.io/blog/1434',
+ },
+ {
+ path:
'/blog/less-components-higher-performance-apache-doris-instead-of-clickhouse-mysql-presto-and-hbase',
+ externalLink: 'https://www.velodb.io/blog/140',
+ },
+ {
+ path: '/blog/linkedcare',
+ externalLink: 'https://www.velodb.io/blog/1373',
+ },
+ {
+ path: '/blog/log-analysis-elasticsearch-vs-apache-doris',
+ externalLink: 'https://www.velodb.io/blog/132',
+ },
+ {
+ path: '/blog/migrate-lakehouse-from-bigquery-to-doris',
+ externalLink: 'https://www.velodb.io/blog/689',
+ },
+ {
+ path: '/blog/migrating-from-clickhouse-to-apache-doris-what-happened',
+ externalLink: 'https://www.velodb.io/blog/138',
+ },
+ {
+ path: '/blog/multi-tenant-workload-isolation-in-apache-doris',
+ externalLink: 'https://www.velodb.io/blog/403',
+ },
+ {
+ path:
'/blog/real-time-analytical-data-platform-for-the-agentic-ai-era',
+ externalLink: 'https://www.velodb.io/blog/1444',
+ },
+ {
+ path:
'/blog/real-time-data-analytics-at-scale-integrating-apache-flink-and-doris',
+ externalLink: 'https://www.velodb.io/blog/1453',
+ },
+ {
+ path:
'/blog/real-time-lakehouse-in-cainiao-large-scale-business-scenarios',
+ externalLink: 'https://www.velodb.io/blog/1454',
+ },
+ {
+ path: '/blog/real-time-update-deep-dive',
+ externalLink: 'https://www.velodb.io/blog/1431',
+ },
+ {
+ path: '/blog/rtabench-250902',
+ externalLink: 'https://www.velodb.io/blog/1465',
+ },
+ {
+ path: '/blog/sf-technology-replaced-presto-with-apache-doris',
+ externalLink: 'https://www.velodb.io/blog/1433',
+ },
+ {
+ path: '/blog/stability-at-scale-how-apache-doris-handles-pressure',
+ externalLink: 'https://www.velodb.io/blog/1449',
+ },
+ {
+ path:
'/blog/telecom-giant-journey-from-clickhouse-to-apache-doris-13pb-in-one-table',
+ externalLink: 'https://www.velodb.io/blog/1440',
+ },
+ {
+ path: '/blog/tencent-music-migrate-elasticsearch-to-doris',
+ externalLink: 'https://www.velodb.io/blog/1395',
+ },
+ {
+ path:
'/blog/top-commercial-bank-migrated-from-elasticsearch-to-apache-doris-for-pb-scale-log-storage-and-analytics',
+ externalLink: 'https://www.velodb.io/blog/1410',
+ },
+ {
+ path:
'/blog/unified-lakehouse-with-apache-doris-and-paimon-xiaomi-achieves-6×-faster-performance',
+ externalLink: 'https://www.velodb.io/blog/1461',
+ },
+ {
+ path: '/blog/variant-in-apache-doris-2.1',
+ externalLink: 'https://www.velodb.io/blog/224',
+ },
+ {
+ path: '/blog/which-powers-observability-better',
+ externalLink: 'https://www.velodb.io/blog/1406',
+ },
+ {
+ path:
'/blog/why-apache-doris-is-best-alternatives-for-real-time-analytics',
+ externalLink:
'https://medium.com/@kxiao.tiger/apache-doris-vs-elasticsearch-6f7c8232e012',
+ },
+];
diff --git a/src/theme/BlogPostItem/index.tsx b/src/theme/BlogPostItem/index.tsx
index 02261174b63..d9e30c905f0 100644
--- a/src/theme/BlogPostItem/index.tsx
+++ b/src/theme/BlogPostItem/index.tsx
@@ -5,7 +5,10 @@ import BlogPostItemContainer from
'@theme/BlogPostItem/Container';
import BlogPostItemHeader from '@theme/BlogPostItem/Header';
import BlogPostItemContent from '@theme/BlogPostItem/Content';
import BlogPostItemFooter from '@theme/BlogPostItem/Footer';
+import useIsBrowser from '@docusaurus/useIsBrowser';
+import { Redirect } from '@docusaurus/router';
import type { Props } from '@theme/BlogPostItem';
+import { BLOG_RELATED_EXTERNAL_LINK } from './blog.data';
import './styles.scss';
@@ -15,8 +18,18 @@ function useContainerClassName() {
return !isBlogPostPage ? 'margin-bottom--xl' : undefined;
}
-export default function BlogPostItem({ children, className }: Props):
JSX.Element {
+export default function BlogPostItem({ children, className }: Props):
React.ReactElement {
const containerClassName = useContainerClassName();
+ const isBrowser = useIsBrowser();
+ if (isBrowser) {
+ for (let item of BLOG_RELATED_EXTERNAL_LINK) {
+ if (location.pathname.startsWith(item.path)) {
+ window.location.href = item.externalLink;
+ return;
+ }
+ }
+ }
+
return (
<BlogPostItemContainer className={clsx(containerClassName, className)}>
<BlogPostItemHeader />
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]