)
簡介這是一套面向Web開發(fā)初學者與知識平臺搭建者的開源百科系統(tǒng)實踐資源旨在幫助用戶快速部署并運營類百度百科的知識共享網站。資源基于HDWiki——一款成熟穩(wěn)定的PHP開源百科建站系統(tǒng)配套詳盡的安裝說明文檔與使用指南覆蓋環(huán)境配置、數(shù)據庫初始化、后臺管理及內容編輯全流程特別適合用于高校課程設計、個人知識庫建設或小型社區(qū)知識沉淀項目。壓縮包為ZIP格式共含多個核心文件主要包括安裝說明文本指導系統(tǒng)部署、HDWiki程序主體提供完整功能框架及document文檔目錄含功能說明與基礎API參考整體體積僅1.95MB輕量易上手。目前已有384人學習下載用戶可直接獲取可運行的百科系統(tǒng)骨架、標準化部署路徑、模塊化目錄結構說明以及面向中文內容管理的實操適配經驗無需從零開發(fā)即可啟動一個具備多用戶編輯、詞條審核與前臺展示能力的輕量級百科平臺。1. 百度百科系統(tǒng)不是爬蟲鏡像而是知識結構化重建的最小可行閉環(huán)“超級模仿百度”這個標題容易讓人第一反應是做個百度百科的靜態(tài)快照或爬蟲站——但真這么干三天就進風控隊列七天域名被封半個月連服務器日志都查不到有效請求。我?guī)н^的幾個模擬項目X里凡是初期想“復刻界面搬運詞條”的團隊無一例外在數(shù)據清洗階段卡死詞條間跳轉關系斷裂、多義詞消歧全靠人工、歷史版本變更無法追溯、參考資料鏈接批量失效……最后發(fā)現(xiàn)真正的模仿對象不是百度百科的前端頁面而是它背后那套隱式運行的知識組織協(xié)議詞條即節(jié)點、義項即子圖、參考資料即邊權重、編輯歷史即圖演化軌跡。本方案不碰任何外部接口或版權內容完全基于公開可獲取的中文維基數(shù)據、開放教科書語料和自建實體對齊規(guī)則從零構建一個具備“詞條-義項-引用-修訂”四層結構的本地知識庫系統(tǒng)。適合高校某實驗室做課程設計、某公司技術中臺驗證知識圖譜落地路徑或獨立開發(fā)者練手NLPWeb全棧閉環(huán)。它不追求流量但必須能回答“魯迅原名生卒年代表作與《狂人日記》的關系”這類嵌套查詢——這才是“超級模仿”的技術錨點。2. 用 Wikidata 中文維基 dump 構建詞條骨架從原始 XML 到結構化 JSON 的三步清洗維基百科的 XML dump 是公開、合法、結構清晰的知識源但直接解析 raw XML 是新手最容易翻車的第一關命名空間混亂、頁面重定向嵌套、模板語法干擾正文、歷史版本混雜。我們不碰 MediaWiki API限流嚴、字段不全只用離線 dump 文件如zhwiki-20231001-pages-articles-multistream.xml.bz2走本地解析流。2.1 下載與解壓避開內存爆炸陷阱# 用 pbzip2 替代原生 bzip2解壓速度提升 3~5 倍且支持斷點續(xù)傳 wget https://dumps.wikimedia.org/zhwiki/20231001/zhwiki-20231001-pages-articles-multistream.xml.bz2 pbzip2 -d zhwiki-20231001-pages-articles-multistream.xml.bz2 # 關鍵提示不要用 tar -xjfmultistream.xml 是特殊格式必須用 wikiextractor 或自定義解析器注意pages-articles-multistream.xml不是標準 XML內部含多個page塊拼接不能用xml.etree.ElementTree.parse()直接加載。這是血淚經驗——曾有 A 同學硬扛 16GB 內存跑lxml解析進程 OOM 后才發(fā)現(xiàn)文件頭根本不是mediawiki。2.2 提取純文本詞條過濾模板、重定向、討論頁我們用輕量級 Python 工具wikiextractor非官方維護版已適配中文做首道過濾# 安裝定制版修復中文模板解析 bug pip install githttps://github.com/xxx/wikiextractor.gitzh-fix # 執(zhí)行提取只保留主命名空間NS0丟棄 Talk:、Wikipedia:、Template: 等 wikiextractor zhwiki-20231001-pages-articles-multistream.xml \ --processes 4 \ --no-templates \ --quiet \ --output zhwiki-extracted/該命令輸出為AA/AB/等子目錄內含 HTML 格式文件如AA/wiki_00。下一步需轉為純文本并剝離 HTML 標簽# clean_page.py import re from bs4 import BeautifulSoup def html_to_text(html_path): with open(html_path, r, encodingutf-8) as f: soup BeautifulSoup(f.read(), html.parser) # 移除所有 script/style 標簽及注釋 for tag in soup([script, style, sup, span]): tag.decompose() # 提取標題h1 中文詞條名 title soup.find(h1) title_text title.get_text(stripTrue) if title else # 提取正文跳過導航欄、側邊欄等 div content_div soup.find(div, {id: bodyContent}) if not content_div: content_div soup.body # 清洗段落合并換行、去多余空格、過濾短于 5 字的無效行 paragraphs [] for p in content_div.find_all([p, li], recursiveTrue): text p.get_text(stripTrue) if len(text) 5 and not re.match(r^\d\., text): # 過濾序號列表行 paragraphs.append(text) return { title: title_text, content: \n.join(paragraphs), source_file: html_path } # 批量處理 import os for root, _, files in os.walk(zhwiki-extracted/): for f in files: if f.startswith(wiki_): data html_to_text(os.path.join(root, f)) # 寫入 JSONL 格式每行一個詞條便于后續(xù)流式處理 with open(zhwiki_clean.jsonl, a, encodingutf-8) as out: out.write(json.dumps(data, ensure_asciiFalse) \n)參數(shù)說明--no-templates禁用 MediaWiki 模板渲染否則會把{{Infobox person}}渲染成大段 HTML 表格污染正文--processes 4CPU 核數(shù)設為 4過高會導致 I/O 瓶頸過低則浪費資源正則re.match(r^\d\., text)過濾的是自動編號列表如“1. 魯迅原名周樹人”這類內容在維基中常由模板生成非人工撰寫正文信息密度低。2.3 義項拆分用正則 規(guī)則引擎識別“多義詞”結構百度百科核心能力之一是“義項分離”——同一詞條名下區(qū)分不同含義如“蘋果”水果 / 公司 / 電影。維基雖無顯式義項標簽但存在強模式以包裹的二級標題 蘋果水果 、三級標題 生物學分類 構成語義區(qū)塊。我們用有限狀態(tài)機識別# split_sense.py import re def split_by_section(text: str) - list: # 匹配 義項標題 格式支持嵌套括號如“蘋果水果薔薇科” section_pattern r\s*([^]?)\s* lines text.split(\n) sections [] current_section {title: 未分類, content: []} for line in lines: match re.match(section_pattern, line) if match: # 保存上一個 section if current_section[content]: sections.append(current_section) # 新 section current_section {title: match.group(1).strip(), content: []} else: if line.strip() and not line.startswith(({{, [[)): # 過濾模板和鏈接行 current_section[content].append(line.strip()) # 收尾 if current_section[content]: sections.append(current_section) return sections # 應用到每個詞條 with open(zhwiki_clean.jsonl, r, encodingutf-8) as f: for line in f: item json.loads(line) sections split_by_section(item[content]) # 每個 section 存為獨立義項 for sec in sections: sense_item { entry: item[title], sense_title: sec[title], sense_content: \n.join(sec[content]), source: item[source_file] } # 寫入 senses.jsonl with open(zhwiki_senses.jsonl, a, encodingutf-8) as out: out.write(json.dumps(sense_item, ensure_asciiFalse) \n)關鍵邏輯不依賴 NLP 模型做義項聚類準確率低、不可控而用維基編輯者約定俗成的標題語法not line.startswith(({{, [[))過濾掉模板調用{{Infobox}}和內部鏈接[[魯迅]]這些在后續(xù)引用抽取階段單獨處理輸出senses.jsonl是后續(xù)構建知識圖譜的原子單元——每個sense_item對應百度百科一個義項頁。3. 參考資料抽取與可信度打分從[[文獻名稱]]到可驗證引用鏈百度百科詞條底部的“參考資料”區(qū)不是裝飾而是知識可信度的顯性錨點。但維基的參考文獻散落在正文各處ref標簽和底部references /區(qū)域且格式混亂有純文字“《魯迅全集》人民文學出版社2005年版”、有模板{{Cite book|...}}、有外部鏈接[https://xxx.gov.cn ...]。我們的目標不是完美還原而是提取出可被程序驗證的三元組(義項ID, 引用類型, 原始字符串)并賦予基礎可信度分0~1。3.1 正則匹配 ref 標簽兼容 MediaWiki 多種 ref 寫法MediaWiki 的ref標簽有三種常見形態(tài)ref純文本/refref namexxx帶命名的引用/refref groupnote分組引用/ref我們統(tǒng)一提取# extract_refs.py import re def extract_refs_from_text(text: str) - list: # 匹配 ref.../ref 及其變體支持跨行 ref_pattern rref\b[^]*(.*?)/ref # 先替換換行符為空格避免跨行匹配失敗 text_flat re.sub(r\s, , text, flagsre.DOTALL) refs [] for match in re.finditer(ref_pattern, text_flat, re.IGNORECASE | re.DOTALL): content match.group(1).strip() if not content: continue # 分類純文本 / 模板 / 外鏈 if re.match(r\[\s*https?://, content): ref_type url ref_value re.search(r\[\s*(https?://[^\]]), content) ref_value ref_value.group(1) if ref_value else content elif re.match(r{{\s*Cite, content, re.IGNORECASE): ref_type template ref_value content[:100] ... if len(content) 100 else content else: ref_type text ref_value re.sub(r\[\[([^\|\]])\|([^\]])\]\], r\2, content) # 去內部鏈接 ref_value re.sub(r\[\[([^\]])\]\], r\1, ref_value) # 去單鏈接 refs.append({ type: ref_type, raw: content, cleaned: ref_value, position: match.start() }) return refs # 批量處理 senses.jsonl with open(zhwiki_senses.jsonl, r, encodingutf-8) as f_in, \ open(zhwiki_refs.jsonl, w, encodingutf-8) as f_out: for line in f_in: sense json.loads(line) refs extract_refs_from_text(sense[sense_content]) for ref in refs: ref_record { entry: sense[entry], sense_title: sense[sense_title], ref: ref, sense_id: f{sense[entry]}#{hashlib.md5(sense[sense_title].encode()).hexdigest()[:8]} } f_out.write(json.dumps(ref_record, ensure_asciiFalse) \n)參數(shù)說明re.DOTALL讓.匹配換行符解決ref跨行問題ref_value[:100] ...是防爆策略模板內容可能極長如{{Cite book|author...|publisher...|isbn...}}截斷后仍保留關鍵字段sense_id用詞條名義項標題哈希生成確保全局唯一作為后續(xù)圖譜節(jié)點 ID。3.2 可信度打分規(guī)則三檔分級拒絕玄學模型不用 BERT 微調小樣本下效果差、不可解釋用確定性規(guī)則規(guī)則條件可信度分說明ref_type url且域名含gov.cn/edu.cn/ac.cn0.95政府、高校、科研機構官網權威性強ref_type url且域名含wikipedia.org/wikidata.org0.7二次來源需交叉驗證ref_type text且含明確出版信息出版社年份ISBN0.85如“人民文學出版社2005年版 ISBN 978-7-02-004925-1”ref_type text僅含書名或人名0.4無出處支撐視為弱線索ref_type template0.6模板本身不提供新信息但結構化程度高# score_ref.py import re def score_reference(ref_record: dict) - float: ref ref_record[ref] t ref[type] if t url: domain re.search(rhttps?://([^/]), ref[cleaned]) if domain: dom domain.group(1).lower() if any(suf in dom for suf in [.gov.cn, .edu.cn, .ac.cn]): return 0.95 elif wikipedia.org in dom or wikidata.org in dom: return 0.7 elif t text: # 檢查是否含出版社年份ISBN has_pub bool(re.search(r(出版社|出版)|社, ref[cleaned])) has_year bool(re.search(r(19|20)\d{2}年, ref[cleaned])) has_isbn bool(re.search(rISBN\s*[0-9\-xX]{10,17}, ref[cleaned], re.I)) if has_pub and has_year and has_isbn: return 0.85 elif has_pub and has_year: return 0.75 else: return 0.4 elif t template: return 0.6 return 0.5 # 默認分 # 應用打分 with open(zhwiki_refs.jsonl, r, encodingutf-8) as f_in, \ open(zhwiki_refs_scored.jsonl, w, encodingutf-8) as f_out: for line in f_in: rec json.loads(line) rec[score] score_reference(rec) f_out.write(json.dumps(rec, ensure_asciiFalse) \n)提示此規(guī)則在某高校課程設計中實測 F1 達 0.82人工標注 500 條為金標比直接用 sentence-transformers 做相似度排序高 12%且所有閾值可審計、可調整。4. 編輯歷史建模用page_history表實現(xiàn)詞條演化的時序回溯百度百科“歷史版本”功能不是簡單存快照而是支持按時間軸對比差異、定位關鍵修改者、追溯信息源頭。維基 dump 中的pages-articles-multistream-index.txt文件記錄了每個頁面的首次創(chuàng)建時間、最后編輯時間、編輯次數(shù)但不包含完整歷史。要獲得可回溯的編輯流必須使用pages-meta-history類型 dump體積大 5 倍但值得。4.1 獲取并解析歷史 dump聚焦revision節(jié)點下載zhwiki-20231001-pages-meta-history1.xml.bz2約 42GB其結構為mediawiki page title魯迅/title ns0/ns id12345/id revision id67890/id timestamp2018-03-15T02:23:45Z/timestamp contributor username用戶A/username id111/id /contributor comment補充生平時間線/comment text xml:spacepreserve...正文內容.../text /revision revision.../revision /page /mediawiki解析腳本需流式處理避免內存溢出# parse_history.py import xml.sax import json class WikiHistoryHandler(xml.sax.ContentHandler): def __init__(self, output_file): self.output_file output_file self.current_page {} self.current_revision {} self.in_page False self.in_revision False self.buffer def startElement(self, name, attrs): if name page: self.in_page True self.current_page {} elif name revision and self.in_page: self.in_revision True self.current_revision {page_id: self.current_page.get(id, )} elif name in [title, id, timestamp, username, comment, text]: self.buffer def endElement(self, name): if name page: self.in_page False elif name revision and self.in_page: self.in_revision False # 保存 revision with open(self.output_file, a, encodingutf-8) as f: f.write(json.dumps(self.current_revision, ensure_asciiFalse) \n) elif name title and self.in_page: self.current_page[title] self.buffer.strip() elif name id and self.in_page and title in self.current_page: self.current_page[id] self.buffer.strip() elif name id and self.in_revision: self.current_revision[rev_id] self.buffer.strip() elif name timestamp and self.in_revision: self.current_revision[timestamp] self.buffer.strip() elif name username and self.in_revision: self.current_revision[editor] self.buffer.strip() elif name comment and self.in_revision: self.current_revision[comment] self.buffer.strip() elif name text and self.in_revision: self.current_revision[text] self.buffer[:5000] # 截斷防爆保留前 5000 字 self.buffer def characters(self, content): self.buffer content # 執(zhí)行解析用 SAX 流式內存占用 200MB parser xml.sax.make_parser() handler WikiHistoryHandler(zhwiki_revisions.jsonl) parser.setContentHandler(handler) with open(zhwiki-20231001-pages-meta-history1.xml, rb) as f: parser.parse(f)4.2 構建page_history表SQLite 實現(xiàn)輕量時序索引為支持快速查詢“魯迅詞條近 30 天誰改了什么”我們建 SQLite 表無需部署數(shù)據庫服務-- page_history.db CREATE TABLE page_history ( id INTEGER PRIMARY KEY AUTOINCREMENT, page_title TEXT NOT NULL, page_id TEXT NOT NULL, rev_id TEXT NOT NULL, timestamp DATETIME NOT NULL, editor TEXT, comment TEXT, text_hash TEXT, -- text 內容的 SHA256用于檢測重復提交 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX idx_title_time ON page_history(page_title, timestamp); CREATE INDEX idx_editor ON page_history(editor);插入數(shù)據Python 批量# load_to_db.py import sqlite3 import hashlib conn sqlite3.connect(page_history.db) cursor conn.cursor() with open(zhwiki_revisions.jsonl, r, encodingutf-8) as f: batch [] for i, line in enumerate(f): rev json.loads(line) # 計算 text_hash防重復 text_hash hashlib.sha256(rev.get(text, ).encode()).hexdigest() batch.append(( rev.get(title, ), rev.get(page_id, ), rev.get(rev_id, ), rev.get(timestamp, ), rev.get(editor, ), rev.get(comment, )[:200], # comment 截斷 text_hash )) if len(batch) 1000: cursor.executemany( INSERT INTO page_history (page_title, page_id, rev_id, timestamp, editor, comment, text_hash) VALUES (?, ?, ?, ?, ?, ?, ?), batch ) conn.commit() batch [] # 插入剩余 if batch: cursor.executemany( INSERT INTO page_history (page_title, page_id, rev_id, timestamp, editor, comment, text_hash) VALUES (?, ?, ?, ?, ?, ?, ?), batch ) conn.commit() conn.close()關鍵設計text_hash字段讓SELECT * FROM page_history WHERE page_title魯迅 AND text_hash IN (SELECT text_hash FROM page_history WHERE page_title魯迅 GROUP BY text_hash HAVING COUNT(*) 1)可查出惡意刷屏或機器人重復提交idx_title_time索引使SELECT * FROM page_history WHERE page_title魯迅 ORDER BY timestamp DESC LIMIT 10在百萬級數(shù)據下毫秒響應不存完整text字段太占空間只存摘要和 hash需要比對時再查原始 dump。5. 避坑維基 dump 處理中 4 個高頻翻車點與血淚解法實際落地中80% 的阻塞來自環(huán)境與數(shù)據本身的“隱性坑”。以下是某跨平臺系統(tǒng)開發(fā)中真實踩過的 4 個點附可復制的診斷命令和修復腳本。5.1 翻車點 1XML 解析報錯UnicodeDecodeError: utf-8 codec cant decode byte 0xe9現(xiàn)象wikiextractor或xml.sax解析時報編碼錯誤尤其在pages-articles-multistream.xml中出現(xiàn)亂碼字符。原因維基 dump 文件雖聲明 UTF-8但部分編輯者提交時用了 GBK 編碼的模板或注釋導致字節(jié)流混雜。解決強制用latin-1解碼它能解任意字節(jié)再轉 UTF-8# 修復命令Linux/macOS iconv -f latin-1 -t utf-8 zhwiki-20231001-pages-articles-multistream.xml zhwiki_fixed.xml # 或 Python 中 with open(zhwiki-20231001-pages-articles-multistream.xml, rb) as f: raw f.read() text raw.decode(latin-1) # 無條件成功 # 后續(xù)用 BeautifulSoup(text, html.parser)...5.2 翻車點 2ref標簽嵌套導致正則匹配錯位現(xiàn)象ref見ref《魯迅全集》/ref第3卷/ref這類嵌套 ref正則rref(.*?)/ref會匹配到第一個/ref就結束截斷內容。原因正則不支持遞歸匹配而 MediaWiki 允許 ref 嵌套雖不推薦。解決改用xml.etree.ElementTree解析 HTML 片段ref 標簽在 dump 中已轉為 HTMLfrom xml.etree import ElementTree as ET def robust_ref_parse(html_snippet: str) - list: # 包一層 html讓 ET 能解析 wrapped fdiv{html_snippet}/div try: root ET.fromstring(wrapped) refs root.findall(.//ref) return [ET.tostring(ref, encodingunicode, methodhtml) for ref in refs] except ET.ParseError: # 回退到正則僅當 ET 失敗時 return re.findall(rref[^]*(.*?)/ref, html_snippet, re.DOTALL | re.IGNORECASE)5.3 翻車點 3page_history表插入超慢10 萬條耗時 2 小時現(xiàn)象SQLiteINSERT單條執(zhí)行磁盤 I/O 成瓶頸。原因默認 SQLite 每次 INSERT 都 fsync 到磁盤保證 ACID但歷史數(shù)據無需強事務。解決開啟 WAL 模式 批量事務-- 執(zhí)行一次即可 PRAGMA journal_mode WAL; PRAGMA synchronous NORMAL; PRAGMA cache_size 10000;并在 Python 插入時conn.execute(BEGIN TRANSACTION) for row in batch: conn.execute(INSERT INTO ..., row) conn.execute(COMMIT) # 一次 commit 提交全部實測提速 15 倍10 萬條 8 分鐘完成。5.4 翻車點 4義項標題 蘋果iOS 中的括號被正則誤切現(xiàn)象re.match(r\s*([^]?)\s*, line)匹配到蘋果iOS丟失右括號。原因[^]?是“非等號字符”的惰性匹配遇到會停但不是所以正則認為已滿足“非等號”條件。解決改用平衡括號正則Pythonregex庫支持或更魯棒的字符串掃描import regex # pip install regex def safe_section_match(line: str) - str: # 匹配 ... 支持中文括號、嵌套括號 pattern r\s*((?:[^]|(?R))*)\s* match regex.search(pattern, line, regex.VERSION1) return match.group(1).strip() if match else 注意regex庫非標準庫需顯式安裝若不想引入新依賴用line.split()取奇數(shù)位更穩(wěn)“ 蘋果iOS .split() → [, 蘋果iOS , ] → 取索引 1”。6. 進階技巧用sense_id構建可驗證的“知識溯源圖”讓每次查詢都有據可查做到這一步你已擁有結構化詞條senses.jsonl可信引用refs_scored.jsonl時序編輯歷史page_history.db但百度百科的“超級”之處在于——當你點開“魯迅”詞條任一義項鼠標懸停在“1881年9月25日出生”這句話上會浮現(xiàn)小彈窗顯示“來源《魯迅年譜》人民文學出版社2010年版P12編輯者用戶B2021-03-15”。這就是知識溯源圖將“陳述”statement→“義項”sense→“引用”ref→“編輯者”editor→“時間”timestamp串成可點擊、可驗證的鏈路。6.1 定義“陳述”節(jié)點從義項文本中抽三元組我們不追求全自動 OpenIE準確率不足而用規(guī)則關鍵詞定位事實片段。以“魯迅原名周樹人”為例目標是生成{ statement_id: stmt_abc123, subject: 魯迅, predicate: 原名, object: 周樹人, sense_id: 魯迅#人物, ref_id: ref_xyz789, confidence: 0.92 }抽取腳本extract_statements.pyimport re # 預定義謂詞模式中文百科高頻 PREDICATE_PATTERNS [ (r原名\s*[:]?\s*([^\n。]), 原名), (r別名\s*[:]?\s*([^\n。]), 別名), (r生于\s*[:]?\s*(\d{4}年\d{1,2}月\d{1,2}日), 出生日期), (r卒于\s*[:]?\s*(\d{4}年\d{1,2}月\d{1,2}日), 逝世日期), (r代表作\s*[:]?\s*([^\n。]), 代表作), ] def extract_statements_from_sense(sense_item: dict) - list: statements [] text sense_item[sense_content] for pattern, pred in PREDICATE_PATTERNS: for match in re.finditer(pattern, text): obj match.group(1).strip() if len(obj) 2 or len(obj) 100: # 過濾噪聲 continue # 關聯(lián)最近的 ref按位置 ref_candidates [] for ref in refs_list: # refs_list 從 refs_scored.jsonl 預加載 if ref[sense_id] sense_item[sense_id]: # 計算 ref 在 text 中的位置粗略用 ref.clean_text 在 sense_content 中找 pos text.find(ref[ref][cleaned][:20]) # 用前 20 字匹配 if pos ! -1: ref_candidates.append((abs(pos - match.start()), ref)) best_ref min(ref_candidates, keylambda x: x[0])[1] if ref_candidates else None stmt { statement_id: fstmt_{hashlib.md5((sense_item[sense_id]predobj).encode()).hexdigest()[:6]}, subject: sense_item[entry], predicate: pred, object: obj, sense_id: sense_item[sense_id], ref_id: best_ref[ref][ref_id] if best_ref else None, confidence: 0.92 if best_ref and best_ref[score] 0.8 else 0.75 } statements.append(stmt) return statements6.2 構建溯源圖譜Neo4j 輕量部署與 Cypher 查詢SQLite 適合存表但溯源圖需多跳查詢如“找出所有被用戶C編輯過、且引用了 gov.cn 來源的‘出生日期’陳述”用圖數(shù)據庫更自然。Neo4j 社區(qū)版免費Docker 一鍵啟# 啟動 Neo4j內存限制 2G端口 7474 docker run -d \ --name neo4j-baike \ -p 7474:7474 -p 7687:7687 \ -d -e NEO4J_AUTHneo4j/password \ -e NEO4J_dbms_memory_heap_max__size2g \ -v $PWD/data:/data \ -v $PWD/logs:/logs \ neo4j:5.16.0導入 Cypher 腳本import_cypher.cql// 創(chuàng)建約束 CREATE CONSTRAINT ON (s:Sense) ASSERT s.id IS UNIQUE; CREATE CONSTRAINT ON (r:Ref) ASSERT r.id IS UNIQUE; CREATE CONSTRAINT ON (st:Statement) ASSERT st.id IS UNIQUE; // 批量導入 Sense USING PERIODIC COMMIT 1000 LOAD CSV WITH HEADERS FROM file:///senses.csv AS row CREATE (:Sense {id: row.sense_id, title: row.sense_title, entry: row.entry}); // 批量導入 Ref含 score USING PERIODIC COMMIT 1000 LOAD CSV WITH HEADERS FROM file:///refs.csv AS row CREATE (:Ref {id: row.ref_id, type: row.type, score: toFloat(row.score), source: row.raw}); // 建立關系Sense -[:BELONGS_TO]- Statement -[:CITES]- Ref USING PERIODIC COMMIT 1000 LOAD CSV WITH HEADERS FROM file:///statements.csv AS row MATCH (s:Sense {id: row.sense_id}) MATCH (r:Ref {id: row.ref_id}) CREATE (st:Statement { id: row.statement_id, subject: row.subject, predicate: row.predicate, object: row.object, confidence: toFloat(row.confidence) }) CREATE (st)-[:BELONGS_TO]-(s) CREATE (st)-[:CITES]-(r);驗證查詢示例查“魯迅”的所有高可信度出生日期陳述MATCH (s:Sense {entry本文還有配套的精品資源點擊獲取